This is my programming assignment. I need to find out the largest among the array of integers using a method written in 8086 programming language. This is my attempt :
#include <iostream.h>
#include <conio.h>
int returnLargest(int a[])
{
int max;
asm mov si,offset a
for(int i=0;i<6;i++) //Assuming six numbers in the array...Can be set to a variable 'n' later
{
asm mov ax,[si]
asm mov max,ax
asm inc si
cout<<max<<"\n"; //Just to see what is there in the memory location
}
asm mov si,offset a
asm mov cx,0000h
asm mov dx, [si]
asm mov cx,06h
skip: asm mov si,offset a
asm mov bx,[si]
asm mov max,bx
asm inc si
abc: asm mov bx,max
asm cmp [si],bx
asm jl ok
asm mov bx,[si]
asm mov max,bx
ok: asm loop abc
asm mov ax,max
return max;
}
void main()
{
clrscr();
int n;
int a[]={1,2,3,4,5,6};
n=returnLargest(a);
cout<<n; //Prints the largest
getch();
}
The expected answer is
1 2 3 4 5 6 6. But what I get is this :
Here I sit down and think... Is'nt it the value at the index i of array actually stored in the memory? Because atleast we were taught that if a[i] is 12(say) then ith memory location has the number 12 written inside it.
Or if the value is'nt stored at the memory location, How do I write into the memory location so as to accomplish the desired task?
Also I request you all to link some material on net/paperback so as to brush-up on these concepts.
EDIT :
The same code in assembly works just fine...
data segment
a db 01h,02h,03h,04h,05h,06h,'$'
max db ?
data ends
code segment
start:
assume cs:code,ds:data
mov ax,data
mov ds,ax
mov si,offset a
mov cx,0000h
back: mov dl,byte ptr [si]
cmp dl,'$'
je skip
inc cx
inc si
jmp back
skip: mov si,offset a
mov bl,byte ptr[si]
mov max,bl
inc si
abc: mov bl,max
cmp [si],bl
jl ok
mov bl,[si]
mov max,bl
ok: loop abc
mov al,max
int 03h
code ends
end start
We can write assembly program code inside c language program. In such case, all the assembly code must be placed inside asm{} block. Let's see a simple assembly program code to add two numbers in c program.
The asm keyword allows you to embed assembler instructions within C code. GCC provides two forms of inline asm statements. A basic asm statement is one with no operands (see Basic Asm), while an extended asm statement (see Extended Asm) includes one or more operands.
The entry point is in assembly because during the early boot phase there is NO facility to call C functions. Before we can call a C function the system should already have a valid stack.
mov si,offset a
is incorrect. When you have a function parameter declared as int a[]
, the function actually receives a pointer. Since you want the pointer value (a
) rather than its address (&a
in C, offset a
in assembly), use mov si, a
.
Additionally, inc si
doesn't seem right - you need to increase si
by sizeof(int)
for each element.
Edit:
You are mixing C++ code (for
loop, cout
) with your assembly. The C++ code is likely to use the same registers, which would cause conflicts. You should avoid doing this.
You also need to find out which registers your function is allowed to change according to the calling convention used. If you use any registers which aren't allowed to change, you need to push
them at the beginning and pop
them at the end.
You will have to make sure your compiler doesnt use your registers. Best way would be to write the entire function in assembly and implement a desired calling convention (c-call or stdcall - whatever). Then call that function from C/C++.
However if you know you will use only one compiler and how it works you shouldnt have any problems by inlining assembler, but it's really a pitfall.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With