AKRichard
October 21st, 2011, 03:06 AM
Hello again all,
I have been working on creating a base class that holds a number in an array of unsigned shorts, the algorithms for the basic math procedures appears to work correctly however, when I run the algorithm to convert the array into a string of the decimal representation of the number I am getting a strange behavior while debugging. If I let the procedure run without any break points, it gives an incorrect value right from the start (even though the string representation it spits out is good till about 3/4 the way through). If I set up 2 break points in specific places to check on the values and run it, the algorithm gives the correct results at every point including what it returns to the calling routine.
I am using microsoft visual c++ 2008 express. I have not read anything that would indicate that I have to watch out for how break points affect running code. The code listings that follow are the relevant ones to the algorithm.
The multiplication routine:
unsigned short* MyBase::Multiply(unsigned short* _val1offset, unsigned short* _val2offset){
unsigned short car=0;
unsigned int _v1=0;
unsigned int _v2=0;
unsigned int _r=0;
unsigned int _temp=0;
unsigned int _retpos=1;
unsigned int _v1pos=1;
unsigned int _v2pos=1;
unsigned int _two=2;
unsigned int _val1size=(*_val1offset);
unsigned int _val2size=(*_val2offset);
unsigned int _retvalsize=_val1size+_val2size;
_retvalsize+=2;
unsigned short* _retval=NULL;
_retval=new unsigned short[_retvalsize];
_retval[0]=_retvalsize-1;
_retvalsize-=1;
__asm{
mov edi, dword ptr _val1offset
mov esi, dword ptr _val2offset
mov ebx, dword ptr _retval
xor ecx, ecx
mov _v1pos, 0x0
mov _v2pos, 0x0
mov _retpos, 0x0
inc edi
inc edi
inc esi
inc esi
add ebx, 0x2
xor eax, eax
ClearLoop:
mov word ptr [ebx],ax
inc ecx
add ebx, 0x2
cmp ecx, _retvalsize
jle ClearLoop
mov cl, 0x10
mov ebx, dword ptr _retval
add ebx, 0x2
MultLoop:
movzx eax, word ptr [edi]
mov _temp, eax //mov v1 element into eax
movzx eax, word ptr [esi]
mul _temp //multiply v1 element by v2 element
mov _temp, eax
movzx eax, word ptr [ebx]
add eax, _temp //add retval in that element to value
mov _temp, eax
movzx eax, car
add eax, _temp // add the carry in
mov _temp, eax
and ax, 0xffff
mov word ptr [ebx], ax
xor eax, eax
mov car, ax
mov eax, _temp
shr eax, cl
mov car, ax
inc edi
inc edi
add ebx, 0x2
mov eax, _v1pos
add eax, 0x1
mov _v1pos, eax
cmp eax, _val1size
jb MultLoop
movzx eax, car
mov word ptr [ebx], ax
xor eax, eax
mov _v1pos, eax
mov car, ax
mov edi, dword ptr _val1offset
inc edi
inc edi
mov ebx, dword ptr _retval
add ebx, 0x2
mov eax, _retpos
add eax, 0x1
mov _retpos, eax
mul _two
add ebx, eax
//mov ebx, eax
mov eax, _v2pos
add eax, 0x1
mov _v2pos, eax
inc esi
inc esi
//mov _v2pos, eax
cmp eax, _val2size
jb MultLoop
mov eax, dword ptr _retval
mov ebx, dword ptr _retval
mov edi,_retvalsize
xor eax, eax
CheckForZero:
mov ax, word ptr [ebx + edi * 2]
cmp ax, 0x0
jne GoOut
dec edi
mov word ptr [ebx], di
cmp edi, 0x0
ja CheckForZero
GoOut:
mov eax, dword ptr _retval
}
return _retval;
}
The exponentiation routine:
unsigned short* MyBase::Pow(unsigned short* _baseoffset, unsigned short* _expoffset){//stuff needs fixed
unsigned int _b=0;//loc _base
unsigned int _e=0;//loc _exp
unsigned int _r=0;//loc _retval
unsigned int _t=0;//loc _tempoffset
unsigned int _sixteen=16;
unsigned int _two=2;
unsigned int _bit=16;
unsigned int _one[]={1};
unsigned int _retvalsize=0;
unsigned int _basesize=(*_baseoffset);
unsigned int _expsize=(*_expoffset);
unsigned int _mtemp=0;
unsigned short _bits[]={1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768};
unsigned short* _retval=NULL;
unsigned short* _tempoffset=NULL;
unsigned short _temp;
unsigned short _temp2;
unsigned short _shift=0;
unsigned short* _tpow=NULL;
_tpow=new unsigned short[2];
_tpow[0]=1;
_tpow[1]=0;
_retvalsize=_basesize*_expoffset[1];
_retval=new unsigned short[_retvalsize+1];
_retval[0]=_retvalsize;
_tempoffset=new unsigned short[_retvalsize+1];
_tempoffset[0]=_retvalsize;
unsigned short * _ttt=NULL;
_ttt=new unsigned short[2];
unsigned int _tttp=0;
__asm{
entry:
mov ebx, dword ptr _ttt
mov _tttp,ebx
mov ebx, dword ptr _baseoffset
mov _b,ebx
mov ecx, dword ptr _expoffset
mov _e,ecx
mov edx, dword ptr _retval
mov _r,edx
mov ebx, dword ptr _tempoffset
mov _t,ebx
start:
mov ebx, _r
mov edx, _t
mov edi, 0x1
xor eax, eax
ClearLoop:
mov word ptr [ebx + edi * 2], ax
mov word ptr [edx + edi * 2], ax
inc edi
cmp edi, _retvalsize
jle ClearLoop
mov edx, _b
xor edi, edi
mov ax, 0x1
mov word ptr [ebx + 2], ax
SetRet:
mov ax, word ptr [edx + edi * 2]
mov word ptr [ebx + edi * 2], ax
inc edi
cmp edi, _basesize
jle SetRet
mov ebx,_b
mov edi, _basesize
CheckBase:
mov ax, word ptr [ebx + edi * 2]
cmp ax, 0x0
jne CheckExponent
dec edi
cmp edi, 0x1
jge CheckBase
mov ax, word ptr [ebx + edi * 2]
cmp ax, 0x0
je ReturnZero
cmp ax, 0x1
je ReturnOne
CheckExponent:
mov ebx, _e
mov edi, _expsize
mov eax, _expsize
cmp eax, 0x1
jg ExpLoop
cmp eax, 0x0
je ReturnOne
mov ax, word ptr [ebx + edi * 2]
cmp ax, 0x0
je ReturnOne
cmp ax, 0x1
je ReturnBase
ExpLoop:
mov ax, word ptr [ebx + edi * 2]
cmp ax, 0x0
jne FindStart
dec edi
cmp edi, 0x1
jge ExpLoop
mov ax, word ptr [ebx + edi * 2]
cmp ax, 0x0
je ReturnOne
cmp ax, 0x1
je ReturnBase
mov ebx, _b
mov edx, _r
mov edi, 0x1
CopyBase:
//mov ax, word ptr [ebx + edi * 2]
//mov word ptr [edx + edi * 2], ax
//inc edi
//cmp edi, _basesize
//jle CopyBase
//mov ebx, _e
//mov edi, _expsize
FindStart:
mov esi, 0xf
mov ax, word ptr [ebx + edi * 2]
mov _temp, ax
mov cl, 0x1
FindOne:
mov ax, _temp
mov _temp2, ax
sal _temp, cl
jc BeginAlg
dec esi
cmp esi, 0x0
jge FindOne
dec edi
cmp edi, 0x0
jg FindStart
mov esi, 0xf
mov ax, word ptr [ebx + edi * 2]
mov _temp, ax
FindOne2:
//mov ax, _temp
//mov _temp2, ax
sal _temp, cl
jc BeginAlg
dec esi
cmp esi, 0x0
jge FindOne2
mov esi, 0xf
dec edi
cmp edi, 0x1
jl ReturnOne
mov ax, word ptr [ebx + edi * 2]
mov _temp, ax
jmp FindOne2
BeginAlg:
//mov ax, _temp2
//mov _temp, ax
StartAlg:
LoopAlg:
push eax
push ebx
push ecx
push edx
push edi
push esi
mov eax, _r
push eax
push eax
call Multiply
mov dword ptr _tpow, eax
Ret1:
mov _r, eax
mov _tttp,eax
mov _ttt,eax
pop eax
pop eax
pop esi
pop edi
pop edx
pop ecx
pop ebx
pop eax
sal _temp, cl
jc DoMult2
Ret2:
dec esi
cmp esi, 0x0
jg StartAlg
mov esi, 0x10
dec edi
cmp edi, 0x1
jl GoOut
mov ax, word ptr [ebx + edi * 2]
mov _temp, ax
jmp LoopAlg
DoMult2:
push eax
push ebx
push ecx
push edx
push edi
push esi
mov eax, _r
push eax
mov eax, _b
push eax
call Multiply
mov dword ptr _tpow, eax
mov _r, eax
mov _tttp,eax
mov _ttt,eax
pop eax
pop eax
pop esi
pop edi
pop edx
pop ecx
pop ebx
pop eax
jmp Ret2
ReturnOne:
mov ebx, _r
mov edi, _retvalsize
LoopItOne:
mov word ptr [ebx + edi * 2], 0x0
dec edi
cmp edi, 0x1
jg LoopItOne
mov word ptr [ebx], 0x1
mov word ptr [ebx + 2], 0x1
jmp GoOut
ReturnZero:
mov ebx, _r
xor edi, edi
inc edi
LoopItTwo:
mov word ptr [ebx + edi * 2], 0x0
inc edi
cmp edi, _retvalsize
jle LoopItTwo
jmp GoOut
ReturnBase:
mov ebx, _b
mov edx, _r
xor edi, edi
LoopItThree:
mov ax, word ptr [ebx + edi * 2]
mov word ptr [edx + edi * 2], ax
inc edi
cmp edi, _basesize
jle LoopItThree
GoOut:
mov eax, _r
mov _retval, eax
}
return _retval;
}
the subtraction routine:
unsigned short* MyBase::Subtract(unsigned short* _val1offset, unsigned short* _val2offset){
unsigned short car=0;
unsigned short _temp;
unsigned int _short=0;
unsigned int _val1size=(*_val1offset);
unsigned int _val2size=(*_val2offset);
unsigned int _retvalsize=_val1size;
if(_val1size>=_val2size){
_short=_val2size;
}
else{
_short=_val1size;
}
unsigned short* _retval=NULL;
unsigned int _two=2;
_retval=new unsigned short[_retvalsize+1];
_retval[0]=_retvalsize;
__asm{
mov ebx, dword ptr _val1offset
mov edi, dword ptr _val2offset
mov esi, dword ptr _retval
xor eax,eax
mov car,ax
ZeroOut:
mov ax, word ptr [ebx]
mov word ptr [esi], ax
inc esi
inc esi
add ebx, 0x2
movzx edx, car
add edx, 0x1
mov car, dx
cmp edx,_val1size
jbe ZeroOut
mov edi, dword ptr _val2offset
mov esi, dword ptr _retval
xor eax,eax
xor ebx, ebx
mov car,ax
inc edi
inc edi
inc esi
inc esi
add ebx, 0x1
sub1:
mov ax, word ptr [esi]
cmp ax, word ptr [edi]
ja DontDoIt
mov _temp,0x1
DontDoIt:
sub ax, word ptr [edi]
sub ax, car
mov cx, _temp
mov car, cx
mov _temp, 0x0
//cmp ax, 0x0
//ja DontAdd
//add ax, 0xffff
//mov car, 0x1
DontAdd:
mov word ptr [esi], ax
inc edi
inc edi
inc esi
inc esi
add ebx, 0x1
cmp ebx, _val2size
jbe Sub1
Val2Over:
cmp ebx, _val1size
ja GoOut
mov ax, car
cmp ax, 0x0
je GoOut
mov ax, word ptr [esi]
sub ax, 0x1
mov car, 0x0
cmp ax, 0x0
jae DontAdd2
add ax, 0xffff
mov car, 0x1
DontAdd2:
mov word ptr [esi], ax
inc esi
inc esi
add ebx, 0x1
jmp Val2Over
GoOut:
mov eax, _retvalsize
mul _two
mov esi, dword ptr _retval
add esi, eax
mov ecx, _retvalsize
CheckForZero:
mov ax, word ptr [esi]
cmp ax, 0x0
ja OutOfHere
dec esi
dec esi
dec ecx
cmp ecx, 0x0
ja CheckForZero
OutOfHere:
mov esi, dword ptr _retval
mov word ptr [esi],cx
mov eax, dword ptr _retval
}
return _retval;
}
and the tostring routine (notice where I put the break points marked bp1 and bp2:
unsigned short* MyBase::ConvertToString(unsigned short* _val1offset){
unsigned short* _retval=NULL;
unsigned short* _tn=NULL;
unsigned short* _exponent=NULL;
unsigned short* _pow=NULL;
unsigned short* _mult=NULL;
unsigned short* _mult2=NULL;
unsigned short* _b10=NULL;
unsigned short* _digit=NULL;
unsigned int _t=0;
unsigned int _e=0;
unsigned int _p=0;
unsigned int _m=0;
unsigned int _m2=0;
unsigned int _b=0;
unsigned int _d=0;
unsigned int _v1=0;
unsigned int _r=0;
unsigned int _ba=0;
unsigned int _da=0;
unsigned int _exponentsize=2;
unsigned int _powsize=2;
unsigned int _multsize=2;
unsigned int _mult2size=2;
unsigned int _b10size=2;
unsigned int _digitsize=2;
unsigned int _val1size=(*_val1offset);
unsigned int _retvalsize=_val1size*5;
unsigned int _tnsize=_val1size;
unsigned int _exp=_val1size*5;
unsigned int _base=10;
unsigned short _barray[]={0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
unsigned short _dec[]={'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
unsigned int _docount=1;
_retval=new unsigned short[_exp];
_retval[0]=_exp;
_tn=new unsigned short[_val1size+1];
_tn[0]=_val1size;
_exponent=new unsigned short[2];
_exponent[0]=1;
_pow=new unsigned short[2];
_pow[0]=1;
_mult=new unsigned short[2];
_mult[0]=1;
_mult2=new unsigned short[2];
_mult2[0]=1;
_b10=new unsigned short[2];
_b10[0]=1;
_b10[1]=_base;
_digit=new unsigned short[2];
_digit[0]=1;
_digit[1]=0;
__asm{
mov eax, dword ptr _barray
mov _ba, eax
mov eax, dword ptr _dec
mov _da, eax
mov edi, dword ptr _retval
inc edi
mov eax, dword ptr _retval
mov _r, eax
mov eax, dword ptr _tn
mov _t, eax
mov eax, dword ptr _exponent
mov _e, eax
mov eax, dword ptr _pow
mov _p, eax
mov eax, dword ptr _mult
mov _m, eax
mov eax, dword ptr _mult2
mov _m2, eax
mov eax, dword ptr _b10
mov _b, eax
mov eax, dword ptr _digit
mov _d, eax
mov eax, dword ptr _val1offset
mov _v1, eax
xor eax, eax
mov ebx, _r
mov esi, eax
xor edi, edi
inc esi
inc edi
ClearRet: //String^ _retval="";
mov word ptr [ebx + esi * 2], ax
inc esi
cmp esi, _val1size
jle ClearRet
mov esi, _val1size
mov ebx, _t
mov edx, _v1
CopyVal:
mov ax, word ptr [edx + esi * 2]
mov word ptr [ebx + esi * 2], ax
dec esi
cmp esi, 0x0
jg CopyVal
mov ax, word ptr [edx]
mov word ptr [ebx], ax
mov ebx, _e
xor ecx, ecx
mov ecx, _exp
DecExp://while(_pow>_tn)
mov word ptr [ebx + 2], cx
push edi
push ecx
push _e
push _b
call MyBase::Pow //_pow=Pow(_b10,_exp);
mov dword ptr _pow, eax
pop edx
pop edx
push _t
push eax
call MyBase::GT //if(_pow>_tn){
pop edx
pop edx
pop ecx
pop edi
cmp eax, 0x0
je FoundExp
dec ecx
mov _exp, ecx
mov ebx, _e
jmp DecExp //_exp-=1
FoundExp://while(_exp>=0){
xor eax, eax
mov ebx, _e
mov word ptr [ebx +2], cx
DigitLoop:
mov ebx, _d
mov word ptr [ebx + 2], ax
push edi
push eax
push ecx
push _e
push _b
call MyBase::Pow // _pow=Pow(_base,_exp);
mov dword ptr _pow, eax
mov _p, eax
pop edx
pop edx
push _p
push _d
call MyBase::Multiply // _mult=_digit*_pow;
mov dword ptr _mult, eax
mov _m, eax
pop edx
pop edx
push _t
push eax
call MyBase::LT // while(_mult<_tn)
mov edx, eax
pop ecx
pop ecx
pop ecx
pop eax
pop edi
cmp edx, 0x1
jb StopInc
inc eax //_digit+=1;
cmp eax, _base //if(_digit<_base){
jl DigitLoop
StopInc:
cmp eax, _base //if(_digit<_base) ok
jl DontDecDigit
dec eax //otherwise _digit-=1
mov ebx, _d
mov word ptr [ebx + 2], ax
jmp DontDec
DontDecDigit:
push edi
push eax
push ecx
push _t
push _m
call MyBase::LTOE //if(_mult<=_tn)
pop edx
pop edx
mov edx, eax
pop ecx
pop eax
pop edi
cmp edx, 0x0
jne DontDec
dec eax //_digit-=1;
mov ebx, _d
mov word ptr [ebx + 2], ax
push edi
push eax
push ecx
push _p
push _d
call Multiply
mov _m, eax
mov dword ptr _mult, eax
pop eax
pop eax
pop ecx
pop eax
pop edi
DontDec:
push edi
push eax
push ecx
push _m
push _t
mov edx, _docount
cmp edx, 0x1
je DoCount
DoCountReturn:
mov eax, _m
mov dword ptr _mult, eax
call MyBase::Subtract// bp1 this gives correct results
mov dword ptr _tn, eax
mov _t, eax// bp1 this gives correct results
pop edx
pop edx
pop ecx
pop eax
pop edi
//xor edx, edx
//mov edx, eax
//xor eax, eax
//mov eax, edx
mov edx, _r
mov word ptr [edx + edi * 2],ax//bp2 this is the other place for a break point but this one doies not produce corrct results
inc edi
cmp ecx, 0x0
je GoOut
dec ecx
jmp FoundExp
DoCount:
xor edx,edx
mov _docount,edx
mov edx, _r
mov word ptr [edx], cx
jmp DoCountReturn
GoOut:
mov eax, dword ptr _retval
}
return _retval;
}
If I put the two break points marked bp1 in so that I can check the values contained in _tn and _mult before the subtraction and after, the program gives the correct result everytime (regardless of if I have the bp2 break point enables or not) but if I do not have the two bp1 enabled, it ALLWAYS gives an incorrect result. Am I doing something wrong here?
As a side note, I am just learning assembly so any other comments about my code are welcome.
Thanks in advance
I have been working on creating a base class that holds a number in an array of unsigned shorts, the algorithms for the basic math procedures appears to work correctly however, when I run the algorithm to convert the array into a string of the decimal representation of the number I am getting a strange behavior while debugging. If I let the procedure run without any break points, it gives an incorrect value right from the start (even though the string representation it spits out is good till about 3/4 the way through). If I set up 2 break points in specific places to check on the values and run it, the algorithm gives the correct results at every point including what it returns to the calling routine.
I am using microsoft visual c++ 2008 express. I have not read anything that would indicate that I have to watch out for how break points affect running code. The code listings that follow are the relevant ones to the algorithm.
The multiplication routine:
unsigned short* MyBase::Multiply(unsigned short* _val1offset, unsigned short* _val2offset){
unsigned short car=0;
unsigned int _v1=0;
unsigned int _v2=0;
unsigned int _r=0;
unsigned int _temp=0;
unsigned int _retpos=1;
unsigned int _v1pos=1;
unsigned int _v2pos=1;
unsigned int _two=2;
unsigned int _val1size=(*_val1offset);
unsigned int _val2size=(*_val2offset);
unsigned int _retvalsize=_val1size+_val2size;
_retvalsize+=2;
unsigned short* _retval=NULL;
_retval=new unsigned short[_retvalsize];
_retval[0]=_retvalsize-1;
_retvalsize-=1;
__asm{
mov edi, dword ptr _val1offset
mov esi, dword ptr _val2offset
mov ebx, dword ptr _retval
xor ecx, ecx
mov _v1pos, 0x0
mov _v2pos, 0x0
mov _retpos, 0x0
inc edi
inc edi
inc esi
inc esi
add ebx, 0x2
xor eax, eax
ClearLoop:
mov word ptr [ebx],ax
inc ecx
add ebx, 0x2
cmp ecx, _retvalsize
jle ClearLoop
mov cl, 0x10
mov ebx, dword ptr _retval
add ebx, 0x2
MultLoop:
movzx eax, word ptr [edi]
mov _temp, eax //mov v1 element into eax
movzx eax, word ptr [esi]
mul _temp //multiply v1 element by v2 element
mov _temp, eax
movzx eax, word ptr [ebx]
add eax, _temp //add retval in that element to value
mov _temp, eax
movzx eax, car
add eax, _temp // add the carry in
mov _temp, eax
and ax, 0xffff
mov word ptr [ebx], ax
xor eax, eax
mov car, ax
mov eax, _temp
shr eax, cl
mov car, ax
inc edi
inc edi
add ebx, 0x2
mov eax, _v1pos
add eax, 0x1
mov _v1pos, eax
cmp eax, _val1size
jb MultLoop
movzx eax, car
mov word ptr [ebx], ax
xor eax, eax
mov _v1pos, eax
mov car, ax
mov edi, dword ptr _val1offset
inc edi
inc edi
mov ebx, dword ptr _retval
add ebx, 0x2
mov eax, _retpos
add eax, 0x1
mov _retpos, eax
mul _two
add ebx, eax
//mov ebx, eax
mov eax, _v2pos
add eax, 0x1
mov _v2pos, eax
inc esi
inc esi
//mov _v2pos, eax
cmp eax, _val2size
jb MultLoop
mov eax, dword ptr _retval
mov ebx, dword ptr _retval
mov edi,_retvalsize
xor eax, eax
CheckForZero:
mov ax, word ptr [ebx + edi * 2]
cmp ax, 0x0
jne GoOut
dec edi
mov word ptr [ebx], di
cmp edi, 0x0
ja CheckForZero
GoOut:
mov eax, dword ptr _retval
}
return _retval;
}
The exponentiation routine:
unsigned short* MyBase::Pow(unsigned short* _baseoffset, unsigned short* _expoffset){//stuff needs fixed
unsigned int _b=0;//loc _base
unsigned int _e=0;//loc _exp
unsigned int _r=0;//loc _retval
unsigned int _t=0;//loc _tempoffset
unsigned int _sixteen=16;
unsigned int _two=2;
unsigned int _bit=16;
unsigned int _one[]={1};
unsigned int _retvalsize=0;
unsigned int _basesize=(*_baseoffset);
unsigned int _expsize=(*_expoffset);
unsigned int _mtemp=0;
unsigned short _bits[]={1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768};
unsigned short* _retval=NULL;
unsigned short* _tempoffset=NULL;
unsigned short _temp;
unsigned short _temp2;
unsigned short _shift=0;
unsigned short* _tpow=NULL;
_tpow=new unsigned short[2];
_tpow[0]=1;
_tpow[1]=0;
_retvalsize=_basesize*_expoffset[1];
_retval=new unsigned short[_retvalsize+1];
_retval[0]=_retvalsize;
_tempoffset=new unsigned short[_retvalsize+1];
_tempoffset[0]=_retvalsize;
unsigned short * _ttt=NULL;
_ttt=new unsigned short[2];
unsigned int _tttp=0;
__asm{
entry:
mov ebx, dword ptr _ttt
mov _tttp,ebx
mov ebx, dword ptr _baseoffset
mov _b,ebx
mov ecx, dword ptr _expoffset
mov _e,ecx
mov edx, dword ptr _retval
mov _r,edx
mov ebx, dword ptr _tempoffset
mov _t,ebx
start:
mov ebx, _r
mov edx, _t
mov edi, 0x1
xor eax, eax
ClearLoop:
mov word ptr [ebx + edi * 2], ax
mov word ptr [edx + edi * 2], ax
inc edi
cmp edi, _retvalsize
jle ClearLoop
mov edx, _b
xor edi, edi
mov ax, 0x1
mov word ptr [ebx + 2], ax
SetRet:
mov ax, word ptr [edx + edi * 2]
mov word ptr [ebx + edi * 2], ax
inc edi
cmp edi, _basesize
jle SetRet
mov ebx,_b
mov edi, _basesize
CheckBase:
mov ax, word ptr [ebx + edi * 2]
cmp ax, 0x0
jne CheckExponent
dec edi
cmp edi, 0x1
jge CheckBase
mov ax, word ptr [ebx + edi * 2]
cmp ax, 0x0
je ReturnZero
cmp ax, 0x1
je ReturnOne
CheckExponent:
mov ebx, _e
mov edi, _expsize
mov eax, _expsize
cmp eax, 0x1
jg ExpLoop
cmp eax, 0x0
je ReturnOne
mov ax, word ptr [ebx + edi * 2]
cmp ax, 0x0
je ReturnOne
cmp ax, 0x1
je ReturnBase
ExpLoop:
mov ax, word ptr [ebx + edi * 2]
cmp ax, 0x0
jne FindStart
dec edi
cmp edi, 0x1
jge ExpLoop
mov ax, word ptr [ebx + edi * 2]
cmp ax, 0x0
je ReturnOne
cmp ax, 0x1
je ReturnBase
mov ebx, _b
mov edx, _r
mov edi, 0x1
CopyBase:
//mov ax, word ptr [ebx + edi * 2]
//mov word ptr [edx + edi * 2], ax
//inc edi
//cmp edi, _basesize
//jle CopyBase
//mov ebx, _e
//mov edi, _expsize
FindStart:
mov esi, 0xf
mov ax, word ptr [ebx + edi * 2]
mov _temp, ax
mov cl, 0x1
FindOne:
mov ax, _temp
mov _temp2, ax
sal _temp, cl
jc BeginAlg
dec esi
cmp esi, 0x0
jge FindOne
dec edi
cmp edi, 0x0
jg FindStart
mov esi, 0xf
mov ax, word ptr [ebx + edi * 2]
mov _temp, ax
FindOne2:
//mov ax, _temp
//mov _temp2, ax
sal _temp, cl
jc BeginAlg
dec esi
cmp esi, 0x0
jge FindOne2
mov esi, 0xf
dec edi
cmp edi, 0x1
jl ReturnOne
mov ax, word ptr [ebx + edi * 2]
mov _temp, ax
jmp FindOne2
BeginAlg:
//mov ax, _temp2
//mov _temp, ax
StartAlg:
LoopAlg:
push eax
push ebx
push ecx
push edx
push edi
push esi
mov eax, _r
push eax
push eax
call Multiply
mov dword ptr _tpow, eax
Ret1:
mov _r, eax
mov _tttp,eax
mov _ttt,eax
pop eax
pop eax
pop esi
pop edi
pop edx
pop ecx
pop ebx
pop eax
sal _temp, cl
jc DoMult2
Ret2:
dec esi
cmp esi, 0x0
jg StartAlg
mov esi, 0x10
dec edi
cmp edi, 0x1
jl GoOut
mov ax, word ptr [ebx + edi * 2]
mov _temp, ax
jmp LoopAlg
DoMult2:
push eax
push ebx
push ecx
push edx
push edi
push esi
mov eax, _r
push eax
mov eax, _b
push eax
call Multiply
mov dword ptr _tpow, eax
mov _r, eax
mov _tttp,eax
mov _ttt,eax
pop eax
pop eax
pop esi
pop edi
pop edx
pop ecx
pop ebx
pop eax
jmp Ret2
ReturnOne:
mov ebx, _r
mov edi, _retvalsize
LoopItOne:
mov word ptr [ebx + edi * 2], 0x0
dec edi
cmp edi, 0x1
jg LoopItOne
mov word ptr [ebx], 0x1
mov word ptr [ebx + 2], 0x1
jmp GoOut
ReturnZero:
mov ebx, _r
xor edi, edi
inc edi
LoopItTwo:
mov word ptr [ebx + edi * 2], 0x0
inc edi
cmp edi, _retvalsize
jle LoopItTwo
jmp GoOut
ReturnBase:
mov ebx, _b
mov edx, _r
xor edi, edi
LoopItThree:
mov ax, word ptr [ebx + edi * 2]
mov word ptr [edx + edi * 2], ax
inc edi
cmp edi, _basesize
jle LoopItThree
GoOut:
mov eax, _r
mov _retval, eax
}
return _retval;
}
the subtraction routine:
unsigned short* MyBase::Subtract(unsigned short* _val1offset, unsigned short* _val2offset){
unsigned short car=0;
unsigned short _temp;
unsigned int _short=0;
unsigned int _val1size=(*_val1offset);
unsigned int _val2size=(*_val2offset);
unsigned int _retvalsize=_val1size;
if(_val1size>=_val2size){
_short=_val2size;
}
else{
_short=_val1size;
}
unsigned short* _retval=NULL;
unsigned int _two=2;
_retval=new unsigned short[_retvalsize+1];
_retval[0]=_retvalsize;
__asm{
mov ebx, dword ptr _val1offset
mov edi, dword ptr _val2offset
mov esi, dword ptr _retval
xor eax,eax
mov car,ax
ZeroOut:
mov ax, word ptr [ebx]
mov word ptr [esi], ax
inc esi
inc esi
add ebx, 0x2
movzx edx, car
add edx, 0x1
mov car, dx
cmp edx,_val1size
jbe ZeroOut
mov edi, dword ptr _val2offset
mov esi, dword ptr _retval
xor eax,eax
xor ebx, ebx
mov car,ax
inc edi
inc edi
inc esi
inc esi
add ebx, 0x1
sub1:
mov ax, word ptr [esi]
cmp ax, word ptr [edi]
ja DontDoIt
mov _temp,0x1
DontDoIt:
sub ax, word ptr [edi]
sub ax, car
mov cx, _temp
mov car, cx
mov _temp, 0x0
//cmp ax, 0x0
//ja DontAdd
//add ax, 0xffff
//mov car, 0x1
DontAdd:
mov word ptr [esi], ax
inc edi
inc edi
inc esi
inc esi
add ebx, 0x1
cmp ebx, _val2size
jbe Sub1
Val2Over:
cmp ebx, _val1size
ja GoOut
mov ax, car
cmp ax, 0x0
je GoOut
mov ax, word ptr [esi]
sub ax, 0x1
mov car, 0x0
cmp ax, 0x0
jae DontAdd2
add ax, 0xffff
mov car, 0x1
DontAdd2:
mov word ptr [esi], ax
inc esi
inc esi
add ebx, 0x1
jmp Val2Over
GoOut:
mov eax, _retvalsize
mul _two
mov esi, dword ptr _retval
add esi, eax
mov ecx, _retvalsize
CheckForZero:
mov ax, word ptr [esi]
cmp ax, 0x0
ja OutOfHere
dec esi
dec esi
dec ecx
cmp ecx, 0x0
ja CheckForZero
OutOfHere:
mov esi, dword ptr _retval
mov word ptr [esi],cx
mov eax, dword ptr _retval
}
return _retval;
}
and the tostring routine (notice where I put the break points marked bp1 and bp2:
unsigned short* MyBase::ConvertToString(unsigned short* _val1offset){
unsigned short* _retval=NULL;
unsigned short* _tn=NULL;
unsigned short* _exponent=NULL;
unsigned short* _pow=NULL;
unsigned short* _mult=NULL;
unsigned short* _mult2=NULL;
unsigned short* _b10=NULL;
unsigned short* _digit=NULL;
unsigned int _t=0;
unsigned int _e=0;
unsigned int _p=0;
unsigned int _m=0;
unsigned int _m2=0;
unsigned int _b=0;
unsigned int _d=0;
unsigned int _v1=0;
unsigned int _r=0;
unsigned int _ba=0;
unsigned int _da=0;
unsigned int _exponentsize=2;
unsigned int _powsize=2;
unsigned int _multsize=2;
unsigned int _mult2size=2;
unsigned int _b10size=2;
unsigned int _digitsize=2;
unsigned int _val1size=(*_val1offset);
unsigned int _retvalsize=_val1size*5;
unsigned int _tnsize=_val1size;
unsigned int _exp=_val1size*5;
unsigned int _base=10;
unsigned short _barray[]={0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};
unsigned short _dec[]={'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
unsigned int _docount=1;
_retval=new unsigned short[_exp];
_retval[0]=_exp;
_tn=new unsigned short[_val1size+1];
_tn[0]=_val1size;
_exponent=new unsigned short[2];
_exponent[0]=1;
_pow=new unsigned short[2];
_pow[0]=1;
_mult=new unsigned short[2];
_mult[0]=1;
_mult2=new unsigned short[2];
_mult2[0]=1;
_b10=new unsigned short[2];
_b10[0]=1;
_b10[1]=_base;
_digit=new unsigned short[2];
_digit[0]=1;
_digit[1]=0;
__asm{
mov eax, dword ptr _barray
mov _ba, eax
mov eax, dword ptr _dec
mov _da, eax
mov edi, dword ptr _retval
inc edi
mov eax, dword ptr _retval
mov _r, eax
mov eax, dword ptr _tn
mov _t, eax
mov eax, dword ptr _exponent
mov _e, eax
mov eax, dword ptr _pow
mov _p, eax
mov eax, dword ptr _mult
mov _m, eax
mov eax, dword ptr _mult2
mov _m2, eax
mov eax, dword ptr _b10
mov _b, eax
mov eax, dword ptr _digit
mov _d, eax
mov eax, dword ptr _val1offset
mov _v1, eax
xor eax, eax
mov ebx, _r
mov esi, eax
xor edi, edi
inc esi
inc edi
ClearRet: //String^ _retval="";
mov word ptr [ebx + esi * 2], ax
inc esi
cmp esi, _val1size
jle ClearRet
mov esi, _val1size
mov ebx, _t
mov edx, _v1
CopyVal:
mov ax, word ptr [edx + esi * 2]
mov word ptr [ebx + esi * 2], ax
dec esi
cmp esi, 0x0
jg CopyVal
mov ax, word ptr [edx]
mov word ptr [ebx], ax
mov ebx, _e
xor ecx, ecx
mov ecx, _exp
DecExp://while(_pow>_tn)
mov word ptr [ebx + 2], cx
push edi
push ecx
push _e
push _b
call MyBase::Pow //_pow=Pow(_b10,_exp);
mov dword ptr _pow, eax
pop edx
pop edx
push _t
push eax
call MyBase::GT //if(_pow>_tn){
pop edx
pop edx
pop ecx
pop edi
cmp eax, 0x0
je FoundExp
dec ecx
mov _exp, ecx
mov ebx, _e
jmp DecExp //_exp-=1
FoundExp://while(_exp>=0){
xor eax, eax
mov ebx, _e
mov word ptr [ebx +2], cx
DigitLoop:
mov ebx, _d
mov word ptr [ebx + 2], ax
push edi
push eax
push ecx
push _e
push _b
call MyBase::Pow // _pow=Pow(_base,_exp);
mov dword ptr _pow, eax
mov _p, eax
pop edx
pop edx
push _p
push _d
call MyBase::Multiply // _mult=_digit*_pow;
mov dword ptr _mult, eax
mov _m, eax
pop edx
pop edx
push _t
push eax
call MyBase::LT // while(_mult<_tn)
mov edx, eax
pop ecx
pop ecx
pop ecx
pop eax
pop edi
cmp edx, 0x1
jb StopInc
inc eax //_digit+=1;
cmp eax, _base //if(_digit<_base){
jl DigitLoop
StopInc:
cmp eax, _base //if(_digit<_base) ok
jl DontDecDigit
dec eax //otherwise _digit-=1
mov ebx, _d
mov word ptr [ebx + 2], ax
jmp DontDec
DontDecDigit:
push edi
push eax
push ecx
push _t
push _m
call MyBase::LTOE //if(_mult<=_tn)
pop edx
pop edx
mov edx, eax
pop ecx
pop eax
pop edi
cmp edx, 0x0
jne DontDec
dec eax //_digit-=1;
mov ebx, _d
mov word ptr [ebx + 2], ax
push edi
push eax
push ecx
push _p
push _d
call Multiply
mov _m, eax
mov dword ptr _mult, eax
pop eax
pop eax
pop ecx
pop eax
pop edi
DontDec:
push edi
push eax
push ecx
push _m
push _t
mov edx, _docount
cmp edx, 0x1
je DoCount
DoCountReturn:
mov eax, _m
mov dword ptr _mult, eax
call MyBase::Subtract// bp1 this gives correct results
mov dword ptr _tn, eax
mov _t, eax// bp1 this gives correct results
pop edx
pop edx
pop ecx
pop eax
pop edi
//xor edx, edx
//mov edx, eax
//xor eax, eax
//mov eax, edx
mov edx, _r
mov word ptr [edx + edi * 2],ax//bp2 this is the other place for a break point but this one doies not produce corrct results
inc edi
cmp ecx, 0x0
je GoOut
dec ecx
jmp FoundExp
DoCount:
xor edx,edx
mov _docount,edx
mov edx, _r
mov word ptr [edx], cx
jmp DoCountReturn
GoOut:
mov eax, dword ptr _retval
}
return _retval;
}
If I put the two break points marked bp1 in so that I can check the values contained in _tn and _mult before the subtraction and after, the program gives the correct result everytime (regardless of if I have the bp2 break point enables or not) but if I do not have the two bp1 enabled, it ALLWAYS gives an incorrect result. Am I doing something wrong here?
As a side note, I am just learning assembly so any other comments about my code are welcome.
Thanks in advance