Reputation: 964
I'm developing a compiler and I have an issue when I try to generate the assembly code from the following custom language code
b:=-2;
c:=-4;
a:=c/b;
to test this result I use a if condition asking if a == 2 but is not.
this is the piece of code generated from the code avobe
mov ax, 1
mov _a, ax
mov ax, -2
mov _b, ax
mov ax, -4
mov _c, ax
mov dx, 0
mov ax, _c
mov bx, _b
cmp bx, 0
JE label_div0Excp // jump to division by 0 message
idiv bx
mov @aux0, ax
mov ax, @aux0
mov _a, ax
mov ax, _a
cmp ax,2
JNE label_1
invoke MessageBox, NULL, addr _message0, addr _message0, MB_OK //_message0 say that result == 2
Can enybody help me with that?
thanks
Upvotes: 2
Views: 2791
Reputation: 25809
The IDIV BX
instruction does a signed divide of DX:AX
by BX
. DX:AX is two 16-bit registers glued together and treated as one 32-bit value. You have zeroed DX, but zeroing DX is not sufficient for signed arithmetic. You need to sign extend AX into DX. In other words, if AX
is positive, DX
should be 0, but if AX
is negative, then DX
needs to be -1, aka 0xFFFF. Conveniently, there is an instruction that does this sign extension without explicit compares or jumps: CWD
(convert word to double).
Try this instead:
mov ax, _c
cwd // <--------------
mov bx, _b
cmp bx, 0
JE label_div0Excp // jump to division by 0 message
idiv bx
Upvotes: 5
Reputation: 58427
IDIV
does signed division, so it expects the dividend in DX:AX
to be a signed doubleword. Instead of clearing DX
prior to the division you should therefore sign-extend AX
into DX:AX
. This can be done with the CWD
instruction.
From Intel's manual: "The CWD
instruction can be used to produce a doubleword dividend from a word before word division."
Upvotes: 7