Умножение. mul и imul

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

Инструкции mul и imul умножает два целых числа. imul умножает числа со знаком, а mul - беззнаковые числа. Инструкция imul имеет следующую общую форму:

imul dest, source

Если инструкции передается два операнда, то она умножает первый операнд на второй и результат присваивает первому операнду:

dest = dest * source

Первый операнд - всегда регистр. Второй операнд может представлять регистр, переменную или константу. Оба операнда должны совпадать по размеру и могут быть 16-, 32- и 64-разрядными, за исключением констант, которые не могут превышать 32 бит (Если первый операнд 64-разрядный, то константы автоматически расширяются со знаком до 64 бит).

Пример умножения:

.code
main proc
    mov eax, 3
    imul eax, 5     ; EAX = EAX * 5 = 3 * 5 = 15
    ret
main endp
end

Также инструкция imul может принимать три операнда:

imul dest, source, constant

Теперь умножаются втрой и третий операнд, а результат помещается в первый операнд:

dest = source * constant

Первый операнд - по прежнему регистр. Второй операнд - регистр или переменная. А третий операнд - константа. При этом операнды также должны соответствовать по разрядности, и могут быть 16-, 32- и 64-разрядными, за исключением констант, которые опять же не должны превышать 32 бит. Пример:

.code
main proc
    mov edx, 3
    imul eax, edx, 4     ; EAX = EDX * 4 = 3 * 4 = 12
    ret
main endp
end

Если при умножении происходит переполнение (которое всегда является переполнением со знаком, поскольку imul умножает только целочисленные значения со знаком), то эта инструкция устанавливает флаги переноса CF и переполнения OF. Другие флаги - флаг знака SF и флаг нуля ZF не определены.

Инструкции mul и imul поддерживают также форму с одним операндом:

mul/imul operand8   ; результат в AX
mul/imul operand16  ; результат в DX:AX
mul/imul operand32  ; результат в EDX:EAX
mul/imul operand64  ; результат в RDX:RAX

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

mul/imul operand8

AX = AL × operand8

mul/imul operand16

DX:AX = AX × operand16

mul/imul operand32

EDX:EAX = EAX × operand32

mul/imul operand64

RDX:RAX = RAX × operand64

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

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

.code
main proc
    xor rax, rax
    mov dx, 5
    mov ax, 4
    mul dx      ; DX:AX = AX * DX = 4 * 5 = 20
    ret
main endp
end
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850