Операнды команд умножения и деления на ассемблере x86, 16-битные и выше

Я не совсем понимаю, как работают операции умножения и деления в сборке x86. Например, приведенный ниже код не кажется слишком сложным, поскольку он имеет дело с 8-битными.

8-битное умножение:

; User Input:
; [num1], 20
; [num2] , 15

mov    ax, [num1]    ; moves the 8 bits into AL
mov    bx, [num2]    ; moves the 8 bits into BL

mul    bl            ; product stored in AX

print  ax

Но что произойдет, если вы захотите умножить два 16-битных числа? Как можно умножить два 16-битных числа так же, как это было сделано с 8-битными числами?

Я не понимаю, в каких регистрах будут храниться значения. Будут ли они храниться в AL и AH или просто сохранится 16-битное число в AX. Чтобы показать, что я имею в виду:

; User Input:
; [num1], 20
; [num2], 15

mov    eax, [num1]    ; Does this store the 16-bit number in AL and AH or just in AX
mov    ebx, [num2]    ; Does this store the 16-bit number in BL and BH or just in BX

mul    ???            ; this register relies on where the 16-bit numbers are stored

print  eax

Может ли кто-нибудь немного рассказать о том, как работает умножение и деление? (особенно с 16-битными и 32-битными числами? Нужно ли мне чередовать биты, если значения хранятся в нижних AL и AH?

Или можно просто mov num1 и num2 в ax и bx соответственно, а затем умножить их, чтобы получить произведение в eax?


person StartingGroovy    schedule 20.03.2012    source источник


Ответы (1)


Быстрый взгляд на документацию показывает, что есть 4 возможных размера операндов для MUL. Входы и выходы сведены в удобную таблицу:

------------------------------------------------------
| Operand Size | Source 1 | Source 2   | Destination |
------------------------------------------------------
| Byte         | AL       | r/m8       | AX          |
| Word         | AX       | r/m16      | DX:AX       |
| Doubleword   | EAX      | r/m32      | EDX:EAX     |
| Quadword     | RAX      | r/m64      | RDX:RAX     |
------------------------------------------------------
person Carl Norum    schedule 20.03.2012
comment
Я смотрел на это и знал, где хранится значение после mul. Мне интересно, когда я сохраняю значение в eax (до mul), если оно хранит его в младших битах (AL и AH), а не в старших битах (AX). Если он хранит их в младших битах, смогу ли я повернуть их в AX, а затем просто умножить AX и BX и распечатать ответ (я думаю, это будет в EAX)? - person StartingGroovy; 21.03.2012
comment
Если вы сохраняете значение в eax, оно находится в всех из eax. Я не уверен, что понимаю. Я думаю, вы могли запутаться, какие части eax тоже ah, al и ax. Вы можете увидеть диаграмму в томе 1 той же документации. В частности, ax относится к тем же 16 битам, что и ah:al, а не к старшим 16 битам eax. - person Carl Norum; 21.03.2012
comment
Ах, вы правы, вот что меня смутило. Итак, по сути, я бы хотел умножить AX на BX, и мой продукт должен быть в EAX? - person StartingGroovy; 21.03.2012
comment
Закрыть, но товар будет в DX:AX. Проверьте таблицу в моем ответе. - person Carl Norum; 21.03.2012
comment
Значит, умножение двух 16-битных чисел не дает 32-битного числа? (Это тоже могло быть причиной того, что меня смутила диаграмма. Я думал, что умножение двух 16-битных чисел даст 32-битное число) - person StartingGroovy; 21.03.2012
comment
Конечно, есть - DX - это 16 бит, а AX - 16 бит. Это делает DX: AX 32-битным числом. 16 + 16 = 32, верно? - person Carl Norum; 21.03.2012
comment
Вау, иногда я думаю, что я полуслеп, когда пытаюсь читать документацию. Я предположил, что это означает, что он хранит значения в AX OR DX, а не в обоих. Последний вопрос перед тем, как я приму ваш ответ: Итак, если я хочу распечатать это, могу ли я переместить DX в EAX, повернуть влево, а затем переместить AX и распечатать EAX? - person StartingGroovy; 21.03.2012
comment
AX уже есть - это нижние 16 бит EAX. Да, вам нужно переместить половину DX вверх в верхнюю половину EAX. - person Carl Norum; 21.03.2012