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
没有办法溢出因为:
7FFFFFFFFFFFFFFF = 9223372036854775807 => sqrt(9223372036854775807) = 3037000499 = 0xB504F333
0xB504F333 * 0xB504F333 < 7FFFFFFFFFFFFFFF (EDX:EAX)
为何溢出?
感谢回复。
答案 0 :(得分:6)
MOV EAX,0xB504F333
MOV ECX,0xB504F333
IMUL ECX
确实必须在0x15F61998
和EDX
0x9EA1DC29
中生成EAX
。那是因为IMUL
将其操作数视为签名。
换句话说,由于0xB504F333
表示2的补码中的负值(因为其最高有效位已设置),因此该指令实际上将0xB504F333-0x100000000=-1257966797
而不是0xB504F333=3037000499
相乘。
所以正确的结果是0x15F619989EA1DC29=1582480462354439209
而不是0x7FFFFFFF9EA1DC29=9223372030926249001
。
由于EDX:EAX
中的64位签名产品不是EAX
的符号扩展值,这意味着签名产品不适合32位,IMUL
设置进位和溢出标志为1.这一点在Intel和AMD CPU手册中有解释。
如果您使用MUL ECX
代替IMUL ECX
,您将在0x7FFFFFFF9EA1DC29=9223372030926249001
中获得EDX:EAX
,并且将再次设置溢出和进位标记,因为现在未签名的产品仍然没有不适合32位。