Когда форме с одним операндом imul
передается 32-битный аргумент (как в вашем случае с EDX
), это фактически означает EAX * EDX
, где EAX
и EDX
являются 32-битными регистрами.
Произведение двух 32-битных значений не обязательно укладывается в 32 бита: полный результат умножения может занимать до 64 бит.Старшие 32 бита ответа будут записаны в регистр EDX
, а старшие 32 бита - в регистр EAX
;это обозначается знаком EDX:EAX
.
Если вам нужны только 32 младших бита результата, используйте форму с 2 операндами imul
;он работает быстрее и не имеет никаких неявных операндов (так что вы можете использовать любые регистры, которые вам удобнее).
imul ecx, esi
делает ecx *= esi
, как вы ожидаете, не касаясь EAX
или EDX
.Это как C, где unsigned x=...;
x *= y;
имеет ту же ширину для результата, что и входные данные.
imul
также имеет непосредственную форму: imul ecx, ebx, 1234
делает ecx = ebx * 1234
.Многие ассемблеры примут imul ecx, 1234
как сокращение для imul ecx, ecx, 1234
.
Эти 32x32 => 32-битные формы imul
работают правильно для подписанного или неподписанного;результаты одного операнда mul
и imul
отличаются только в верхней половине (в EDX
), но не в младшей половине EAX
.
См. Справочное руководство по Intelзапись для imul
.