Ассемблер

Как работает MUL в ассемблере

MUL в x86-ассемблере выполняет беззнаковое умножение. У этой инструкции есть важная особенность: один операнд задается явно, а второй берется из аккумулятора автоматически. Результат получается шире исходных операндов и записывается в пару регистров: AX, DX:AX, EDX:EAX или RDX:RAX в зависимости от размера

Пример для 8 бит

mov al, 5
mov bl, 3
mul bl

Здесь mul bl умножает AL на BL. Результат попадает в AX

После выполнения:

AX = 15

Даже если оба числа 8-битные, результат хранится в 16-битном AX, потому что произведение может не поместиться в 8 бит

Пример для 32 бит

mov eax, 1000
mov ebx, 20
mul ebx

Инструкция умножает EAX на EBX. Результат попадает в пару:

EDX:EAX

Если результат помещается в EAX, EDX будет нулевым. Если не помещается, старшая часть окажется в EDX

Таблица размеров

Размер операнда Скрытый операнд Явный операнд Результат
8 бит AL r/m8 AX
16 бит AX r/m16 DX:AX
32 бит EAX r/m32 EDX:EAX
64 бит RAX r/m64 RDX:RAX

Это ключ к пониманию mul: результат почти всегда нужно искать не только в одном регистре

MUL и IMUL

MUL — беззнаковое умножение. Если числа знаковые, используйте IMUL. Например, для отрицательных значений mul даст не тот смысл, который ожидают при обычной signed-арифметике

Как проверить результат в отладчике

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

Хорошее упражнение: сначала умножьте 1000 * 20, потом число, которое не помещается в 32 бита. Так сразу станет видно, почему результат mul шире одного регистра

Флаги после MUL

MUL влияет на CF и OF. Если старшая половина результата не нулевая, эти флаги устанавливаются. Это признак, что результат не поместился в младшую часть

Для 32-битного умножения: если EDX не ноль, произведение не поместилось только в EAX

Частые ошибки

Ждут два явных операнда

В форме mul ebx второй операнд уже скрыт в eax. Это не mul eax, ebx

Не смотрят старшую часть результата

После 32-битного mul проверяйте EDX:EAX, а не только EAX

Используют MUL для отрицательных чисел

Для знакового умножения нужен imul

Не очищают регистры перед расчетом

Перед умножением убедитесь, что в аккумуляторе именно то значение, которое нужно умножить

Мини-пример проверки

mov eax, 4000000000
mov ebx, 2
mul ebx

Результат не поместится в 32 бита, поэтому важна старшая часть в EDX. Если смотреть только EAX, вы увидите обрезанное значение

Что почитать дальше по ассемблеру

Если нужен общий маршрут по теме, откройте рубрику ассемблеру. Для соседних задач пригодятся эти разборы:

Как проверить результат на практике

Для ассемблера важно сначала понять, под какую среду написан пример: DOSBox/TASM, Linux x64/NASM, Visual Studio/MASM или микроконтроллер. Один и тот же смысл может записываться разным синтаксисом, поэтому не переносите команды между средами вслепую. Создайте отдельную папку для примера, сохраните файл с расширением .asm, выполните сборку именно тем инструментом, который указан в уроке, и сравните вывод или состояние регистров с ожидаемым результатом

Если пример не собирается, читайте первую ошибку ассемблера: обычно она указывает на строку, неизвестную инструкцию, неверную метку, неправильную секцию или конфликт синтаксиса. Исправляйте одну ошибку за раз. В ассемблере это особенно важно, потому что маленькая опечатка в метке, регистре или размере операнда может полностью изменить поведение программы

Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные

Настройки cookie

0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x