Ассемблер

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

DIV в x86-ассемблере выполняет беззнаковое деление. У инструкции есть важная особенность: делимое берется не из одного регистра, а из пары регистров. Частное попадает в аккумулятор, а остаток — в старший регистр. Поэтому перед div нужно подготовить не только eax или rax, но и edx или rdx

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

mov eax, 100
xor edx, edx
mov ebx, 7
div ebx

Что произойдет:

  • EDX:EAX образуют делимое;
  • EBX содержит делитель;
  • после div ebx частное будет в EAX;
  • остаток будет в EDX.

Для примера 100 / 7:

EAX = 14
EDX = 2

Потому что 100 = 14 * 7 + 2

Почему нужно очищать EDX

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

xor edx, edx

Это обнуляет старшую часть делимого

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

Размер делителя Делимое Частное Остаток
8 бит AX AL AH
16 бит DX:AX AX DX
32 бит EDX:EAX EAX EDX
64 бит RDX:RAX RAX RDX

Эта таблица — главный ключ к div. Если смотреть только на eax, можно пропустить остаток или не понять, почему возникает ошибка деления

DIV и IDIV

DIV работает с беззнаковыми числами. Для знакового деления используют IDIV. Перед idiv старшую часть делимого готовят иначе: например, через cdq для 32-битного деления или cqo для 64-битного

Если число может быть отрицательным, div не подходит

Что вызывает ошибку

Ошибка деления может возникнуть в двух случаях:

  • делитель равен нулю;
  • частное не помещается в регистр назначения.

Например, если результат слишком большой для eax, процессор не «молча обрежет» его, а выдаст исключение деления

Как проверить код

Для учебного примера используйте маленькие числа:

mov eax, 25
xor edx, edx
mov ecx, 4
div ecx

Ожидаемый результат:

EAX = 6
EDX = 1

Смотрите оба регистра в отладчике. Если результат не совпадает с ожиданием, сначала проверьте значение делителя и содержимое EDX перед самой инструкцией div

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

Не очищают EDX

Самая частая ошибка новичка. Для div ecx делимое — EDX:EAX, а не только EAX

Делят на ноль

Перед div проверяйте делитель

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

Для signed-деления нужен idiv

Теряют остаток

Остаток после 32-битного деления лежит в EDX

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

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

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

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

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

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

Настройки cookie

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