Reputation: 1
I'm trying to write a code to find the greatest common divisor (GCD). The code I wrote works perfectly fine, but I need to write the same code using the EDI register instead of the EAX register. But when I replace "EAX" with "EDI" in the code, it doesn't work as intended. I believe the issue is with the DIV(not sure though)...
.386
.model flat, Stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD
.data
x sword 33
y sword 242
.code
main proc
mov eax, 0
mov esi, 0
mov ax, x
mov si, y
main endp
;----------
CalcGCD Proc ;calculate greatest common divisor
;receive x in eax(int 1) and y in esi(int 2)
;returns x in eax = gcd
;----------
push esi
push edx
cmp eax,0 ;if x >=0
jge LX
neg eax ; x was negative, so make negative
LX:
cmp esi,0 ;if y >=0
jge LY
neg esi ; y was negative, so make negative
LY:
DO: mov edx,0
DIV esi ; edx= eax%esi
mov eax, esi ;eax =esi
mov esi,edx ;esi=edx
cmp esi, 0 ;while esi>0
jg do ;jump back to DO
pop edx
pop esi
ret
CalcGCD ENDP
end main
Upvotes: 0
Views: 99
Reputation: 37212
The div
instruction (and the idiv
instruction) uses implied ("hard wired") registers for the dividend, the quotient and the remainder; and only the divisor is explicit (determined by the programmer).
More specifically, the dividend must be in (e/r)dx:(e/r)ax
, the quotient will be put in (e/r)ax
and the remainder will be put in (e/r)dx
. In your case (32-bit with esi
as the divisor) the 64-bit dividend must be in edx:eaz
(or, split in half with the highest 32 bits in edx
and the lowest 32 bits in eax
).
There's no alternative to the div
and idiv
instructions (except for themselves - i.e. you could use idiv
instead of div
but it won't help), and because there's no alternative you will need to move/copy values from edi
into eax
(and move/copy the result from eax
back to edi
); and if you're moving/copying values like that it's nicer to do it outside the loop (and not inside the loop).
In other words, you want almost all of the code that you already had (that uses eax
) to remain the same, and just want a mov eax,edi
at the start and a mov edi,eax
at the end (possibly with push eax
and pop eax
if eax
is supposed to be unmodified).
The other option is to expect the caller to put the value in eax
themselves, and this is likely to be more efficient (because the caller is likely to have less restrictions on which registers it uses for what); but that can be translated into "stop wanting to do what you wanted to do".
Upvotes: 2