2012-01-08 60 views
0
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 

這是沒有辦法,因爲溢出:x86 IMUL結果是正確的,爲什麼?

7FFFFFFFFFFFFFFF = 9223372036854775807 => sqrt(9223372036854775807) = 3037000499 = 0xB504F333 
0xB504F333 * 0xB504F333 < 7FFFFFFFFFFFFFFF (EDX:EAX) 

爲什麼溢出?

感謝回覆。

+4

這是不是很清楚你在做什麼,你問什麼。對於我來說,提交的代碼不是實際的代碼('IMUL CX RESUL'將不能編譯),列出32位值和寄存器('EAX = B504F333'和'ECX = B504F333')以及在相同時間的16位寄存器('IMUL CX RESUL','DX = 15F61998','AX = 9EA1DC29','7FFFFFFFFFFFFFFF(DX:AX)')。你究竟在做什麼,實際上有問題? – 2012-01-08 09:26:14

+0

對不起,我糾正,結果=>結果 – flatronka 2012-01-08 09:32:57

+0

對不起,它仍然沒有意義。如果實際指令是'IMUL CX',那麼DX:AX中的結果必須是'00A3:DC29',但你卻說它是'1998:DC29'。給我們實際的代碼和數據。 – 2012-01-08 09:40:57

回答

6
MOV EAX,0xB504F333 
MOV ECX,0xB504F333 
IMUL ECX 

確實必須出示在EDX0x15F619980x9EA1DC29EAX。這是因爲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,你會得到EDX:EAX0x7FFFFFFF9EA1DC29=9223372030926249001和溢出和進位標誌將被重新設定,因爲現在的無符號的產品還是不適合32位。

+0

我只使用1個操作數版本IMUL ECX。 – flatronka 2012-01-08 09:40:54

+0

謝謝,一切都很清楚,對不正確的信息感到抱歉 – flatronka 2012-01-08 10:17:30

相關問題