Question

I am working on a Mix program in C++ and Assembly Language(8086) to find smallest number from an array. Here is my code

#include<iostream>
#include<conio.h>
using namespace std;
void main()
{
__int16 a[5],x,y,res;
int i,j;
y=999;

cout<<"\n Enter 5 Numbers:";
for(i=0;i<5;i++)
{
    cin>>a[i];
}

_asm{
    mov bx,y
}

//Finding smallest
for(i=0;i<5;i++)
{
    x=a[i];
    _asm{
        mov ax,x
        cmp ax,bx
        jge nxt
        mov bx,ax
        nxt:
    }
}

_asm{
    mov res,bx;
}

cout<<"\n Smallest Element:"<<res;
getch();
}

The above code is written in Visual Studio 2010 and seems to be working fine. But when I update the same code for Turbo c++ (i.e. changing "iostream" to "iostream.h", removing "using namespace std;", changing "__int16" to "int" etc), it does not work. The answer produced after execution is wrong.

Here is my TC++ program for same

#include<iostream.h>
#include<conio.h>
void main()
{
int a[5],x,y,res;
int i,j;
y=999;

cout<<"\n Enter 5 Numbers:";
for(i=0;i<5;i++)
{
    cin>>a[i];
}

_asm{
    mov bx,y
}

//Finding smallest
for(i=0;i<5;i++)
{
    x=a[i];
    _asm{
        mov ax,x
        cmp ax,bx
        jge nxt
        mov bx,ax
    }
    nxt:
}

_asm{
    mov res,bx;
}

cout<<"\n Smallest Element:"<<res;
getch();
}

Why TC++ and Visual Studio 10 do not give same answer?

Was it helpful?

Solution

You can't expect registers to retain their values between assembly snippets. You have three assembly snippets, with chunks of C between them, and they rely on bx staying the same. The compiler makes no such promise.

Either use memory to store the running minimum, or reformulate with a single assembly snippet. For the latter approach, you'd have to rewrite the for loop and the array access in assembly; it's quite doable. Like this:

_asm{
mov dx, y ; we'll use dx instead of bx for the running minimum - long story
mov bx, a   ; that's the array pointer
mov si, 0 ; that's our i
loop:
    mov ax, [bx+si*2] ; read a[i] into ax; *2 because int is two bytes
    cmp ax,dx
    jge nxt
    mov dx, ax
    nxt:
    ;Now the for loop stuff
    inc si ; i++
    cmp si, 5 ; compare i to 5
    jl loop   ; if less, continue looping
; End of loop
mov res,dx;
}

I'm using bx and si for base+index memory access because on early x86 CPUs, you could only do that kind of memory access with a limited subset of registers (bx or bp for base, si or di for index). These days, you can use any combination of registers; but I'm not sure if antique Turbo C would take that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top