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
Run Code Online (Sandbox Code Playgroud)
它没有办法溢出因为:
7FFFFFFFFFFFFFFF = 9223372036854775807 => sqrt(9223372036854775807) = 3037000499 = 0xB504F333
0xB504F333 * 0xB504F333 < 7FFFFFFFFFFFFFFF (EDX:EAX)
Run Code Online (Sandbox Code Playgroud)
为何溢出?
谢谢你的回复.
MOV EAX,0xB504F333
MOV ECX,0xB504F333
IMUL ECX
Run Code Online (Sandbox Code Playgroud)
的确应该产生0x15F61998
在EDX
和0x9EA1DC29
中EAX
.那是因为IMUL
将其操作数视为签名.
换句话说,因为0xB504F333
在2的补码中表示负值(因为其最高有效位被设置),所以指令实际上是倍增0xB504F333-0x100000000=-1257966797
而不是0xB504F333=3037000499
自身.
所以正确的结果是0x15F619989EA1DC29=1582480462354439209
代替0x7FFFFFFF9EA1DC29=9223372030926249001
.
由于64位签名产品EDX:EAX
不是符号扩展值EAX
,这意味着签名产品不适合32位,因此IMUL
将进位和溢出标志设置为1.这一点在Intel和AMD CPU手册中有所说明. .
如果你使用MUL ECX
的不是IMUL ECX
,你会得到0x7FFFFFFF9EA1DC29=9223372030926249001
的EDX:EAX
,溢出和进位标志将被重新设定,因为现在的无符号的产品还是不适合32位.