neilobremski
Experienced Member
Or more specifically:
What it comes down to is that you cannot safely jump (JS / JNS) based on a signed multiply or divide.
The fix is to re-test the highest byte of the result (DH, AH or AL depending ...):
Instead of relying on a jump to make sure the result is positive (absolute value), I could also use some bit-masking tricks like so ...
This works great so long as you don't care about destroying the modulus (remainder) value left in DX after a 16-bit signed divide.
The CF, OF, SF, ZF, AF, and PF flags are undefined.
What it comes down to is that you cannot safely jump (JS / JNS) based on a signed multiply or divide.
Code:
MOV AX, FF00 ;
CWD ; DX:AX = -256
MOV BX, 0012 ; BX = +18
IDIV BX ;
JNS $+4 ; WRONG!
NEG AX ; AX = ABS(DX:AX / BX)
The fix is to re-test the highest byte of the result (DH, AH or AL depending ...):
Code:
MOV AX, FF00 ;
CWD ; DX:AX = -256
MOV BX, 0012 ; BX = +18
IDIV BX ;
OR AH, AH ; RIGHT!
JNS $+4 ;
NEG AX ; AX = ABS(DX:AX / BX)
Instead of relying on a jump to make sure the result is positive (absolute value), I could also use some bit-masking tricks like so ...
Code:
MOV AX, FF00 ;
CWD ; DX:AX = -256
MOV BX, 0012 ; BX = +18
IDIV BX ;
CWD ;
XOR AX, DX ; AX = ABS(DX:AX / BX)
This works great so long as you don't care about destroying the modulus (remainder) value left in DX after a 16-bit signed divide.