• Please review our updated Terms and Rules here

IDIV and IMUL do not set Sign Flag

neilobremski

Experienced Member
Joined
Oct 9, 2016
Messages
55
Location
Seattle, USA
Or more specifically:

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.
 
You can save a byte by using SAHF instead of OR AH, AH (SAHF is great when you need to check some bit in AH). Also, a couple of mistakes: $+2 jumps to the next instruction, not over it. And AX (and DX:AX) is -256, not -128.

OK, I'm done nitpicking. ;)
 
Thanks Krille. I often forget about SAHF and didn't even consider it could be used to check flags in AH (for some reason I didn't think SAHF even set any flags).
 
Oh man, I need to write something up on SAHF. I honestly thought it was to save the flags INTO AH and not the other way around. Whoops
 
neilobremski;bt1014 said:
Oh man, I need to write something up on SAHF. I honestly thought it was to save the flags INTO AH and not the other way around. Whoops
That's what LAHF does. Great when you need to save some flag but don't want to use the stack (and AH is available for use of course).
 
Back
Top