Для обработки целочисленных значений в низкоуровневом коде применяются команды DIV и IDIV. Первая работает с беззнаковыми числами, вторая – со знаковыми. Операнд-делитель указывается явно, а делимое всегда берется из пары регистров: AX (16-бит), DX:AX (32-бит) или EDX:EAX (64-бит).
Перед выполнением операции необходимо обнулить DX (для беззнакового варианта) или расширить знак через CWD/CDQ. Игнорирование этого шага приведет к некорректному результату. Например, перед делением AX на BL требуется выполнить XOR DX, DX для 16-битного формата.
Результат сохраняется в AX (частное) и DX (остаток). Для 32-битных чисел используются EAX и EDX. Ошибка #DE (Divide Error) возникает при переполнении или делении на ноль – обработчик исключений должен быть настроен заранее.
Работа с операциями дробления в низкоуровневом коде
Команды для целочисленного вычисления
В x86 применяются инструкции DIV и IDIV. Первая работает с беззнаковыми значениями, вторая – со знаковыми. Операнд указывает делитель, а делимое всегда берётся из пары регистров:
- Для 8-битных операций: AX / операнд → результат в AL, остаток в AH.
- Для 16-битных: DX:AX / операнд → AX (частное), DX (остаток).
- Для 32-битных: EDX:EAX / операнд → EAX, остаток в EDX.
Пример для 16-битного беззнакового случая:
mov ax, 1000 ; Делимое (младшая часть)
mov dx, 0 ; Старшая часть
mov bx, 30 ; Делитель
div bx ; AX = 33, DX = 10
Особенности обработки ошибок
При переполнении или попытке дробления на ноль процессор генерирует исключение #DE. Для избежания сбоев проверяйте делитель перед выполнением операции:
test bx, bx
jz division_error ; Переход, если BX = 0
Для знаковых значений используйте CWD, CDQ или CQO (в зависимости от разрядности), чтобы расширить знак делимого в DX/EDX/RDX перед IDIV.
Работа с целыми числами в x86
Для обработки целых значений используйте команды DIV и IDIV. Первая работает с беззнаковыми числами, вторая – со знаковыми. Операнд указывает делитель, а делимое всегда берётся из пары регистров:
- 8-битное: AX (результат – AL, остаток – AH)
- 16-битное: DX:AX (результат – AX, остаток – DX)
- 32-битное: EDX:EAX (результат – EAX, остаток – EDX)
Особенности обработки ошибок
При нулевом делителе или переполнении возникает исключение #DE. Перед операцией обнулите EDX для беззнаковых значений или используйте CDQ для знаковых.
Код для 32-битного беззнакового случая:
mov eax, 200 ; Делимое
mov ebx, 5 ; Делитель
xor edx, edx ; Очистка EDX
div ebx ; EAX = 40, EDX = 0
Для отрицательных чисел:
mov eax, -200
mov ebx, 3
cdq ; Расширение EAX в EDX:EAX
idiv ebx ; EAX = -66, EDX = -2
Контроль ошибок и переполнения при работе с операциями
Проверяйте флаг переполнения (OF) после выполнения команды IDIV
или DIV
. Если он установлен, результат не поместился в регистр назначения.
Типичные сценарии сбоев
- Деление на ноль – вызывает прерывание #DE (Divide Error).
- Результат выходит за границы диапазона для
AX/DX:AX/EDX:EAX
. - Остаток превышает размер делителя (например, при
DX >= divisor
для 16-битных значений).
Практические методы проверки
- Перед операцией:
- Сравните делитель с нулём:
CMP divisor, 0
+ условный переход. - Для знаковых значений: убедитесь, что
DX:AX
содержит корректное число (например,TEST DX, DX
передIDIV CX
).
- Сравните делитель с нулём:
- После операции:
- Анализируйте флаги процессора:
JO label_overflow
. - Проверяйте остаток (
DX/RDX/EDX
) на соответствие ожидаемому диапазону.
- Анализируйте флаги процессора:
Пример обработки прерывания #DE:
mov ax, -32768
mov bl, -1
idiv bl ; Вызовет переполнение (результат 32768 > 127)
jo handle_overflow
Как выполнить операцию деления с помощью DIV и IDIV
Для беззнакового вычисления применяйте DIV
, для знакового – IDIV
. Операнд указывается явно, но делимое всегда берется из пары AX
, DX:AX
или EDX:EAX
в зависимости от размера:
- 8-битное: делимое в
AX
, результат –AL
(частное),AH
(остаток). - 16-битное: делимое в
DX:AX
, результат –AX
(частное),DX
(остаток). - 32-битное: делимое в
EDX:EAX
, результат –EAX
(частное),EDX
(остаток).
Перед выполнением IDIV
расширьте знак в DX
или EDX
через CWD
, CDQ
. Например:
mov ax, -100 ; Делимое
cwd ; Расширение знака в DX
mov bx, 3 ; Делитель
idiv bx ; AX = -33, DX = -1
Ошибка (#DE) возникает при переполнении или делении на 0. Проверяйте делитель перед операцией.