Assembler - язык неограниченных возможностей


Деление


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





Начало  Назад  Вперед