Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Архитектура компьютеров / 6_Доп программы.doc
Скачиваний:
44
Добавлен:
20.03.2015
Размер:
164.35 Кб
Скачать

Переполнения и прерывания

Используя команды DIV и особенно IDIV, очень просто вызвать переполнение. Прерывания приводят (по крайней мере в системе, используемой при тестировании этих программ) к непредсказуемым результатам. В операциях деления предполагается, что частное значительно меньше, чем делимое. Деление на нуль всегда вызывает прерывание. Но деление на 1 генерирует частное, которое равно делимому, что может также легко вызвать прерывание.

Рекомендуется использовать следующее правило: если делитель - байт, то его значение должно быть меньше, чем левый байт (АН) делимого; если делитель - слово, то его значение должно быть меньше, чем левое слово (DX) делимого.

Проиллюстрируем данное правило для делителя, равного 1:

Операция деления:

Делимое Делитель Частное

Слово на байт: 0123 01 (1)23

Двойное слово на слово: 0001 4026 0001 (1)4026

В обоих случаях частное превышает возможный размер. Для того чтобы избежать подобных ситуаций, полезно вставлять перед командами DIV и IDIV соответствующую проверку. В первом из следующих примеров предположим, что DIVBYTE - однобайтовый делитель, а делимое находится уже в регистре AX. Во втором примере предположим, что DIVWORD - двухбайтовый делитель, а делимое находится в регистровой паре DX:AX.

Слово на байт Двойное слово на байт

CMP AH,DIVBYTE CMP DX,DIVWORD

JNB ;переполнение JNB ;переполнение

DIV DIVBYTE DIV DIVWORD

Для команды IDIV данная логика должна учитывать тот факт, что либо делимое, либо делитель могут быть отрицательными, а так как сравниваются абсолютные значения, то необходимо использовать команду NEG для временного перевода отрицательного значения в положительное.

Деление вычитанием

Если частное велико, а делитель маленький, то деление можно выполнить с помощью циклического вычитания. Метод заключается в том, что делитель вычитается из делимого и в этом же цикле частное увеличивается на 1. Вычитание продолжается до тех пор, пока делимое остается больше делителя. В следующем примере делитель находится в регистре AX, а делимое - в EBX, частное вырабатывается в CX:

SUB CX,CX ;Очистка частного

С20: CMP AX,BX ;Если делимое < делителя,

JB СЗ0 ;то выйти

SUB AX,BX ;Вычит. делит. из делимого

INC CX ;Инкремент частного

JMP С20 ;Повторить цикл

СЗ0: RET ;Частное в CX, остаток в AX

В конце подпрограммы регистр CX будет содержать частное, а AX - остаток. Пример умышленно примитивен, цель его -продемонстрировать данный способ деления. Если частное получается в регистровой паре DX:AX, то необходимо сделать два дополнения:

1. В метке С20 сравнивать AX и BX только при нулевом DX.

2. После команды SUB вставить команду SBB DX,00 (Вычитание с заимствованием).

Примечание: очень большое частное и малый делитель могут вызвать тысячи циклов.

Соседние файлы в папке Архитектура компьютеров