Умножение. Инструкция mul

Последнее обновление: 23.09.2023

Для умножения беззнаковых чисел применяется команда mul, к которой добавляется суффикс типа данных

  • mulq: для умножения 64-разрядных чисел

  • mull: для умножения 32-разрядных чисел

  • mulw: для умножения 16-разрядных чисел

  • mulb: для умножения 8-разрядных чисел

Она принимает один операнд - регистр или адрес в памяти и умножает его на значение в регистре RAX. Результат помещается в регистры RAX/RDX:

mulb operand8   # результат в AX
mulw operand16  # результат в DX:AX
mull operand32  # результат в EDX:EAX
mulq operand64  # результат в RDX:RAX

В качестве операнда можно передавать регистр или переменную/адрес в памяти. Единственный операнд умножается на соответствующий его размеру регистр AL/AX/EAX/RAX. Результат умножения двух n-битных значений может потребовать 2×n бит. Следовательно, если операнд - 8-битное число, то для результата может потребоваться 16 бит. Аналогично, 16-битный операнд дает 32-битный результат и т.д.

mulb operand8

AX = AL × operand8

mull operand16

DX:AX = AX × operand16

mull operand32

EDX:EAX = EAX × operand32

mulq operand64

RDX:RAX = RAX × operand64

В AX/EAX/RAX помещается младшая часть результата, а в DX/EDX/RDX - старшая.

Если результат умножения по количеству бит больше разрядности операндов, то инструкция mul устанавливает флаг переноса CF и флаг переполнения OF. Пример использования

.globl _start
.text
_start:
    movq $2, %rdi
    movq $4, %rax
    mulq %rdi           # RAX = RAX * RDI
    movq %rax, %rdi     # RDI = RAX = 8
    movq $60, %rax
    syscall

Здесь в регистр RAX помещается число 4, а в регистр RDI - число 2. При выполнении инструкции mulq %rdi значения регистров RAX и RDI будут перемножаться, и результат помещен в регистр RAX. То есть в RAX будет число 2 * 4 = 8. Затем из RAX число копируем в регистр RDI.

Возьмем чуть по сложнее пример, где результат умножения раскидан по регистрам RDX/RAX:

.globl _start
.text
_start:
    movq $0xC000000000000002, %rdi
    movq $4, %rax
    mulq %rdi           # RDX:RAX = RDI * RAX

    movq %rdx, %rdi     # помещаем в RDI старшие 64 бита результата -  RDI = RDX = 3
    movq $60, %rax  # RAX = 60
    syscall

Здесь 8-байтное число 0xC000000000000002 из регистра RDI умножается на число 4. Результатом будет шестнадцатеричное число 0x03_0000000000000008 (в десятичной системе это число 55340232221128654856). Однако для этого числа требуется 66 бит (точнее 9 байт), что превышает размер регистра RAX. Поэтому старшие 2 бита помещаются в регистр RDX. Соответственно после выполнения инструкции movq %rdx, %rdi в регистре RDI будет число 3.

Для умножения чисел со знаком применяется инструкция imul, которая работает аналогично.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850