Сборка Как перевести код операции IMUL (только с одним опрандом) в код C - PullRequest
1 голос
/ 13 октября 2011

Скажи, что я получил

EDX = 0xA28

EAX = 0x0A280105

Я запускаю этот код ASM

IMUL EDX

который, насколько я понимаю, использует только EAX .. если указан один опранд

Так что в коде C это должно быть похоже на

EAX *= EDX;

правильно

После поиска в отладчике .. Я обнаружил, что EDX тоже изменился.

0x0A280105 * 0xA28 = 0x67264A5AC8

в отладчике

EAX = 264A5AC8 EDX = 00000067

теперь, если вы возьмете ответ 0x67264A5AC8 и разделите первую шестнадцатеричную пару, 0x67 264A5AC8 Вы можете ясно видеть, почему EDX и EAX такие, какие они есть.

Хорошо, переполнение происходит ... поскольку оно не может хранить такое огромное число в 32 бита. поэтому он начинает использовать дополнительные 8 бит в EDX

Но у меня вопрос, как бы мне теперь сделать это в коде C, чтобы получить те же результаты?

Полагаю, это будет похоже на

EAX *= EDX;
EDX = 0xFFFFFFFF - EAX; //blah not good with math manipulation like this.

1 Ответ

1 голос
/ 13 октября 2011

Инструкция IMUL фактически выдает результат, вдвое превышающий размер операнда (если только вы не используете одну из более новых версий, которая может указывать пункт назначения). Итак:

imul 8bit -> result = ax, 16bits
imul 16bit -> result = dx:ax, 32bits
imul 32bit -> result = edx:eax, 64bits

Чтобы сделать это в C, будет зависеть от компилятора, но некоторые будут работать следующим образом:

long result = (long) eax * (long) edx;
eax = result & 0xffffffff;
edx = result >> 32;

Предполагается, что long составляет 64 бита. Если у компилятора нет 64-битного типа данных, тогда вычисление результата становится намного сложнее, вам нужно сделать длинное умножение.

Вы всегда можете вставить инструкцию imul.

...