| [Назад] [Далее] | ![]() |
Общий алгоритм деления числа любого размера на число любого размера нельзя построить с использованием команды DIV — такие операции выполняются при помощи сдвигов и вычитаний и оказываются весьма сложными. Рассмотрим сначала менее общую операцию (деление любого числа на слово или двойное слово), которую можно легко выполнить с помощью команд DIV:
; деление 64-битного числа divident на 16-битное число divisor.
; Частное помещается в 64-битную переменную quotent,
; а остаток - в 16-битную переменную modulo
mov ax,word ptr divident[6]
xor dx,dx
div divisor
mov word ptr quotent[6],ax
mov ax,word ptr divident[4]
div divisor
mov word ptr quotent[4],ax
mov ax,word ptr divident[2]
div divisor
mov word ptr quotent[2],ax
mov ax,word ptr divident
div divisor
mov word ptr quotent,ax
mov modulo,dx
Деление любого другого числа полностью аналогично — достаточно только добавить нужное число троек команд mov/div/mov в начало алгоритма.
Наиболее очевидный алгоритм для деления чисел любого размера на числа любого размера — деление в столбик с помощью последовательных вычитаний делителя (сдвинутого влево на соответствующее количество разрядов) из делимого, увеличивая соответствующий разряд частного на 1 при каждом вычитании, пока не останется число, меньшее делителя (остаток):
; деление 64-битного числа в EDX:EAX на 64-битное число в ЕСХ:ЕВХ.
; Частное помещается в EDX:EAX, и остаток - в ESI:EDI
mov ebp,64 ; счетчик бит
xor esi,esi
xor edi,edi ; остаток = 0
bitloop:
shl eax,1
rcl edx,1
rcl edi,1 ; сдвиг на 1 бит влево 128-битного числа
rcl esi,1 ; ESI:EDI:EDX:EAX
cmp esi,ecx ; сравнить старшие двойные слова
ja divide
jb next
cmp edi,ebx ; сравнить младшие двойные слова
jb next
divide:
sub edi,ebx
sbb esi,ecx ; ESI:EDI = EBX:ECX
inc eax ; установить младший бит в ЕАХ
next:
dec ebp ; повторить цикл 64 раза
jne bitloop
Несмотря на то что этот алгоритм не использует сложных команд, он выполняется на порядок дольше, чем одна команда DIV.