5.4.4. Деление

Общий алгоритм деления числа любого размера на число любого размера нельзя построить с использованием команды DIV - такие операции выполняют­ся при помощи сдвигов и вычитаний и оказываются весьма сложными. Рассмот­рим сначала менее общую операцию (деление любого числа на слово или двойное слово), которую можно легко осуществить с помощью команд DIV:

; Деление 64-битного числа divident на 16-битное число divisor. ;  Частное помещается в 64-битную переменную quotent,

;   а остаток - в 16-битную переменную modulo.

mov ах,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

Деление любого другого числа полностью аналогично - достаточно только добавить нужное число троек команд mov/div/mov в начало алгоритма.

Наиболее очевидный алгоритм для деления чисел любого размера на числа любого размера — деление в столбик с помощью последовательных вычитаний делителя (сдвинутого влево на нужное количество разрядов) из делимого, чивая соответствующий разряд частного на 1 при каждом вычитании, пока не останется число, меньшее делителя (остаток):

; Деление 64-битного числа в EDX:EAX на 64-битное число

; Частное помещается в EDX:EAX, и остаток - в ESI:EDI.

в ЕСХ:ЕВХ.

mov

;

Счетчик битов.

xor

esi,esi

 

xor

edi.edi

;  Остаток = 0.

bitloop: shl

eax, 1

 

rcl edx,1

 

rcl

edi Д

; Сдвиг на 1 бит влево 128-битного

rcl

esi, 1

; Е51:Еи1:ЕиХ:ЕАХ.

cmp

;

Сравнить старшие двойные слова.

ja

divide

 

jb

next

 

числа.

divide:

next:

crop

edi,ebx

;  Сравнить младшие двойные слова.

jb

next

 

sub

edi,ebx

 

sbb

esi,ecx

ESI:EDI = EBX:ECX.

inc

eax ;

Установить младший бит в ЕАХ.

dec

ebp

•  Повторить цикл 64 раза.

jne

bitloop

 

Несмотря на то что этот алгоритм не использует сложных команд, он выпол­няется на порядок дольше, чем одна команда DIV.