Reputation: 1081
MOV EAX,0XB504F333
MOV ECX,0XB504F333
;EAX = B504F333
;ECX = B504F333
IMUL ECX ;RESULT=
------------------------------
;EDX = 15F61998 ;it is incorrect the correct value is 7FFFFFFF
;EAX = 9EA1DC29 ;it is correct
;Carry flag = 1
;Overflow flag = 1
;Sign flag = 0
It's no way to overflow because:
7FFFFFFFFFFFFFFF = 9223372036854775807 => sqrt(9223372036854775807) = 3037000499 = 0xB504F333
0xB504F333 * 0xB504F333 < 7FFFFFFFFFFFFFFF (EDX:EAX)
Why overflow?
Thanks the replies.
Upvotes: 0
Views: 2384
Reputation: 62106
MOV EAX,0xB504F333
MOV ECX,0xB504F333
IMUL ECX
Must indeed produce 0x15F61998
in EDX
and 0x9EA1DC29
in EAX
. That's because IMUL
treats its operands as signed.
In other words, since 0xB504F333
represents a negative value in 2's complement code (because its most significant bit is set), the instruction actually multiplies 0xB504F333-0x100000000=-1257966797
instead of 0xB504F333=3037000499
by itself.
And so the correct result is 0x15F619989EA1DC29=1582480462354439209
instead of 0x7FFFFFFF9EA1DC29=9223372030926249001
.
Since the 64-bit signed product in EDX:EAX
is not the sign extended value of EAX
, which means that the signed product doesn't fit into 32 bits, IMUL
sets the carry and overflow flags to 1. This all is explained in the Intel and AMD CPU manuals.
If you use MUL ECX
instead of IMUL ECX
, you will get 0x7FFFFFFF9EA1DC29=9223372030926249001
in EDX:EAX
and the overflow and carry flags will be set again because the now unsigned product still doesn't fit into 32 bits.
Upvotes: 6