[Назад] [Далее]

5.4.4. Деление

Общий алгоритм деления числа любого размера на число любого размера нельзя построить с использованием команды 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.


п»ї
"target=_blank><\/a>") //-->