x86 IMUL результат правильный, почему? - PullRequest
0 голосов
/ 08 января 2012
    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)

Почему переполнение?

Спасибо за ответы.

1 Ответ

6 голосов
/ 08 января 2012
MOV EAX,0xB504F333
MOV ECX,0xB504F333
IMUL ECX

Должно действительно производить 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.

Если вы используете MUL ECX вместо IMUL ECX, вы получите 0x7FFFFFFF9EA1DC29=9223372030926249001 в EDX:EAX, и флаги переполнения и переноса будут установлены снова, поскольку неподписанный продукт по-прежнему не помещается в 32 бита.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...