проблема в понимании mul и imul инструкциях Ассемблера

Я извлекаю уроки 80386 из блока ПК paul caurter

  mul source
  • Если операнд является измеренным байтом, он умножается на байт в регистре AL, и результат хранится в 16 битах AX.

отлично.

  • Если источник является 16-разрядным, он умножается на слово в AX, и 32-разрядный результат хранится в DX:AX.

Q1: Почему DX:AX? Почему это не может сохранить в EAX / EDX?

imul действительно сбивает с толку

imul dest, source1
imul dest, source1, source2

alt text

У меня есть проблема в понимании таблицы.

Q2: в 2-й записи таблицы. Снова, почему DX:AX. Почему не EAX или EDX?

Теперь рассмотрите следующий фрагмент кода:

imul eax ; edx:eax = eax * eax
mov ebx, eax ; save answer in ebx
mov eax, square_msg ; square_msg db "Square of input is ", 0
call print_string ; prints the string eax
mov eax, ebx 
call print_int ;  prints the int stored in eax
call print_nl ; prints new line

Q3: Его previsously сказанный это The notation EDX:EAX means to think of the EDX and EAX registers as one 64 bit register with the upper 32 bits in EDX and the lower bits in EAX. Таким образом, ответ также хранится в edx, правильно? в вышеупомянутом коде мы не рассматривали EDX, который мы просто отсылаем к EAX, Как это все еще работает?

Q4: у меня есть проблема с отдыхом всех записей в таблице. худший результат умножения случая двух n укусил числа (n = 16.08.32, биты) 2n биты. Каким образом его хранение результата двух умножения на 16/32 бита приводит к регистру того же размера самого?

8
задан Glorfindel 23 May 2019 в 07:03
поделиться

4 ответа

Q1/Q2: Набор команд x86 сохраняет свою 16-битную историю. При 16-битном умножении ответ хранится в DX:AX. Так оно и есть, потому что так оно и было в 16-битной стране.

Q3: Код, который вы показали, имеет ошибку при попытке вычислить квадрат числа больше 2^16, потому что код игнорирует старшие 32 бита результата, сохраненного в edx.

Q4: Я думаю, что вы можете неправильно прочитать таблицу. 8-битные умножения хранятся в 16-битном результате; 16-битные умножения хранятся в 32-битном результате; 32-битные умножения хранятся в 64-битном результате. На какую именно строку Вы ссылаетесь?

.
8
ответ дан 5 December 2019 в 08:52
поделиться

Существует множество различных вариантов битового кода imul instruction.2.

Вариант, на который вы наткнулись, это 16-битное умножение. Он умножает регистр AX с тем, что вы передаете в качестве аргумента для имитации, и сохраняет результат в DX:AX.

Один 32-битный вариант работает как 16-битное умножение, но записывает регистр в EDX:EAX. Для использования этого варианта достаточно использовать 32-битный аргумент.

Например:

  ; a 16 bit multiplication:
  mov ax, [factor1]
  mov bx, [factor2]
  imul bx              ; 32-bit result in DX:AX
  ; or  imul  word [factor2]

  ; a 32 bit multiplication:
  mov eax, [factor1]
  mov ebx, [factor2] 
  imul ebx             ; 64-bit result in EDX:EAX

На 386 или более поздней версии вы также можете записать imul в виде двух операндов. Это делает его гораздо более гибким и легким в работе. В этом варианте вы можете свободно выбирать любые 2 регистра в качестве исходного и конечного, и процессор не будет тратить время на написание полуфинального результата нигде. И не уничтожит EDX.

  mov   ecx, [factor1]
  imul  ecx, [factor2]    ; result in ecx, no other registers affected
  imul  ecx, ecx          ; and square the result

Или для подписанных 16-битных входов в соответствии с вашим имулом. (используйте movzx для неподписанных входов)

  movsx   ecx, word [factor1]
  movsx   eax, word [factor2]  ; sign-extend inputs to 32-bit
  imul    eax, ecx             ; 32-bit multiply, result in EAX
  imul    eax, eax             ; and square the result

Этот вариант имула был введен с 386, и доступен в 16- и 32-битных размерах операндов. (И размер 64-битного операнда в 64-битном режиме).

В 32-битном коде всегда можно предположить, что доступны 386 инструкций типа imul reg, reg/mem, но его можно использовать в 16-битном коде, если Вас не волнуют старые CPU.

286 ввел 3-операционный и немедленный вид.

imul  cx, bx, 123        ; requires 286

imul  ecx, ebx, 123      ; requires 386
6
ответ дан 5 December 2019 в 08:52
поделиться

Q1/Q2: Я думаю, что причина историческая. До того, как 32-битный вариант был опцией, не было ни воска, ни редактора. 32-битная функциональность была добавлена для обратной совместимости.

Q3: биты низкого порядка будут в eax. Это единственные, о которых вы беспокоитесь, если только не произойдет переполнение в старшие биты.

Q4: Определенно нечетная таблица. Думаю, вы ее поняли.

1
ответ дан 5 December 2019 в 08:52
поделиться

A1: mul изначально присутствовал на процессорах 8086/8088/80186/80286, на которых не было E** (E для расширенного, i. e. 32-битные) регистры.

A2: См. A1.

Поскольку моя работа в качестве программиста ассемблерного языка перешла в семейство Motorola 680x0 до того, как эти 32-битные Intels стали обычным я остановлюсь на этом :-)

.
1
ответ дан 5 December 2019 в 08:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: