знаковое число находится в dx:ax, надо разделить его на cx (тоже знаковое), но заранее известно что произойдет переполнение. Как разделить числа в два или более приемов чтобы получился корректный результат?
Я так и думал, но например в общем случае если у меня в dx:ax находится 0000:ffff, то есть +65535, и мне надо разделить его на 1, то при втором делении программа вылетает. Что-то не так? Вот код, на выходе в dx:ax знаковое число. Код, на входе в dx:ax знаковое 32битное число: Код (Text): push ax ;сохраняем младшую часть делимого mov ax,dx ;старшую помещаем в AX cwd ;расширяем знаки в DX idiv cx ;делим mov bx,ax ;сохраняем в BX результат первого деления pop ax ;восстанавливаем младшую часть делимого в AX idiv cx ;остаток в DX, делим mov dx,bx
Старшие 16 разрядов делимого (без учёта знака, т.е. биты 30:15) должны быть меньше, чем разряды делителя (опять-таки без знака). В случае делимого 0000:FFFF старшие 15 (без знака) разрядов равны 0001, то есть они равны делителю 0001, посему и происходит вылет. ИМХО, можно попробовать сначала разделить делимое на степень двойки (арифметическими сдвигами вправо), пока её старшие 16 разрядов (без знака) не станут меньше, чем 15 разрядов делителя. Потом полученное модифицированное делимое разделить с помощью IDIV, а затем уже, зная, на сколько разрядов оно было сдвинуто, откорректировать частное и остаток.
Честно я сам для себя пишу, просто потом с 32битной арифметикой вылезет все равно точно такая же проблема: буду делить числа размещенные в eax:edx на ecx, и все равно вопрос вылезет. Так что если я сейчас разберусь, то и все проблемы даже не появятся.
Что-то вы тут не то делаете Давайте по шагам разберем eax = 0x0000FFFF edx = 0x0 ecx = 1 push ax ;сохраняем младшую часть делимого mov ax,dx ;старшую помещаем в AX (eax = 0 !!!) cwd ;расширяем знаки в DX idiv cx ;делим ( 0/1 ??) mov bx,ax ;сохраняем в BX результат первого деления pop ax ;восстанавливаем младшую часть делимого в AX (ax = 0xFFFF) idiv cx ;остаток в DX, делим mov dx,bx Что говорит ваш отладчик? Что у вас в регистрах вначале выполнения кода? что в старшей части edx?
Я думаю вам стоит взглянуть на длинную арифметику. И работать не только с регистрами, но и с памятью.