Sadda.ru Ironetcart Андроид Ассемблер MASM32 Linux Все статьи Table of Contents


 

Деление (DIV, IDIV)

  Макс Петров май 2013

      Мнемониками DIV, IDIV записывают команды процессору, обозначающие соответственно беззнаковое деление и деление чисел со знаком.

      Формат команд:

DIV делитель IDIV делитель

где делитель - это 8-, 16-, 32-битный регистр или 8-, 16-, 32-битная переменная.

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

      Делимое должно быть помещено:
      в AX - если делитель имеет размерность байт, тогда после деления частное находим в регистре AL, остаток от деления - в регистре AH;
      в DX:AX - если делитель имеет размерность слово (2 байта), тогда после деления частное находим в регистре AX, остаток от деления - в регистре DX;;
      в EDX:EAX - если делитель имеет размерность двойное слово (4 байта), тогда после деления частное находим в регистре EAX, остаток от деления - в регистре EDX.

      При делении на слово или двойное слово делимое должно быть "расписано" на два регистра. Запись DX:AX означает делимое в виде двойного слова, два старших байта которого помещены в DX, два младших байта - в AX. Запись EDX:EAX означает делимое в виде учетверенного слова (8 байт), четыре старших байта которого помещены в EDX, четыре младших байта - в EAX.

      В беззнаковом делении, если делимое не имеет разрядов в той части, которая должна быть помещена в DX или EDX, регистр DX или EDX просто обнуляют. В знаковом делении используют команды cbw, cwd, cdq, при выполнении которых все старшие биты заполняются нулями - для положительных чисел, или единицами - для отрицательных чисел. Команда cbw знаково преобразует (расширяет) содержимое регистра AL до AX, команда cwd преобразует AX до DX:AX, команда cwde преобразует AX до EAX, команда cdq преобразует EAX до EDX:EAX.

      В случае превышения (overflow) результатом деления размера того регистра, куда должен быть помещен этот результат, дальнейшее выполнение программы прерывается операционной системой. При беззнаковом делении на байт максимально допустимое частное составляет 255, при делении на слово - 65535. Ввиду малого диапазона обрабатываемых чисел и самого результата, деление на байт или слово, как операция, поддерживаемая современными процессорами Intel, имеет значение, в основном, для обеспечения совместимости с предыдущими версиями процессоров и соответствующими (устаревшими) программами. Однако, чем меньше размерность делителя, тем быстрее выполняется команда, и деление на байт и слово могут и теперь (при подходящих условиях) сослужить пользу в алгоритмах с большими объемами вычислений и критичных ко времени исполнения. Так, для 386-процессоров выполнение деления на двойное слово требует 38 тактов процессора, на слово - 22 такта, на байт - 14 тактов.

      Примеры приведены ниже. О функциях PrintLine, PrintText, PrintDec см. VKDEBUG

.386 .model flat, stdcall option casemap :none include <\masm32\include\windows.inc> include <\masm32\include\kernel32.inc> includelib <\masm32\lib\kernel32.lib> include <\masm32\include\user32.inc> includelib <\masm32\lib\user32.lib> include <\masm32\include\masm32.inc> includelib <\masm32\lib\masm32.lib> include <\masm32\include\debug.inc> includelib <\masm32\lib\debug.lib> .data byteVar byte 155 ; 1 байт: +155 или -101 fwordVar fword 4294967551 ; 6 байт (побайтно: "000 001 000 000 000 155") qwordVar qword 4294967551 ; 8 байт (побайтно: "000 000 000 001 000 000 000 155") byteDivider byte 10 ; делитель размерностью 1 байт wordDivider word 10 ; делитель размерностью 2 байта dwordDivider dword 10 ; делитель размерностью 4 байта .code start: ; =================== ; =================== PrintLine PrintText "БЕЗЗНАКОВОЕ ДЕЛЕНИЕ" PrintLine PrintText "ДЕЛИМ 155 (BYTE) НА 10 (BYTE):" mov AL, byteVar mov AH, 0 ; расширяем делимое до AX DIV byteDivider PrintDec AL, "частное" ; по выполнении в AL - "15" PrintDec AH, "остаток" ; по выполнении в AH - "5" PrintLine PrintText "ДЕЛИМ 155 (BYTE) НА 10 (WORD):" mov AL, byteVar mov AH, 0 ; расширяем делимое до AX mov DX, 0 ; расширяем делимое до DX:AX DIV wordDivider PrintDec AX, "частное" ; по выполнении в AX - "15" PrintDec DX, "остаток" ; по выполнении в DX - "5" PrintLine PrintText "ДЕЛИМ 155 (BYTE) НА 10 (DWORD):" mov EAX, 0 ; расширяем делимое до EAX mov EDX, 0 ; расширяем делимое до EDX:EAX mov AL, byteVar DIV dwordDivider PrintDec EAX, "частное" ; по выполнении в EAX - "15" PrintDec EDX, "остаток" ; по выполнении в EDX - "5" PrintLine PrintText "ДЕЛИМ 4294967551 (FWORD) НА 10 (DWORD):" lea EBX, fwordVar ; получаем адрес нулевого байта fwordVar mov EDX, 0 ; обнуляем EDX (два старших байта) mov DX, word ptr [EBX+4] ; посылаем в DX два старших байта fwordVar mov EAX, dword ptr [EBX] ; посылаем в EAX четыре младших байта fwordVar DIV dwordDivider PrintDec EAX, "частное" ; по выполнении в EAX - "429496755" PrintDec EDX, "остаток" ; по выполнении в EDX - "1" PrintLine PrintText "ДЕЛИМ 4294967551 (QWORD) НА 10 (ECX):" lea EBX, qwordVar ; получаем адрес нулевого байта qwordVar mov EDX, dword ptr [EBX+4] ; посылаем в EDX четыре старших байта qwordVar mov EAX, dword ptr [EBX] ; посылаем в EAX четыре младших байта qwordVar mov ECX, 10 DIV ECX PrintDec EAX, "частное" ; по выполнении в EAX - "429496755" PrintDec EDX, "остаток" ; по выполнении в EDX - "1" PrintLine ; =================== ; =================== PrintLine PrintText "ЗНАКОВОЕ ДЕЛЕНИЕ" PrintLine PrintText "ДЕЛИМ -101 (БАЙТ) НА +10 (БАЙТ):" mov AL, byteVar cbw ; расширяем делимое (AL) до AX IDIV byteDivider PrintDec AL, "частное" ; по выполнении в AL - "-10" PrintDec AH, "остаток" ; по выполнении в AH - "-1" PrintLine PrintText "ДЕЛИМ -101 (БАЙТ) НА +10 (СЛОВО):" mov AL, byteVar cbw ; расширяем делимое (AL) до AX cwd ; расширяем делимое (AX) до DX:AX IDIV wordDivider PrintDec AX, "частное" ; по выполнении в AX - "-10" PrintDec DX, "остаток" ; по выполнении в DX - "-1" PrintLine PrintText "ДЕЛИМ -101 (БАЙТ) НА +10 (ДВОЙНОЕ СЛОВО):" mov AL, byteVar cbw ; расширяем делимое (AL) до AX cwde ; расширяем делимое (AX) до EAX cdq ; расширяем делимое (EAX) до EDX:EAX IDIV dwordDivider PrintDec EAX, "частное" ; по выполнении в EAX - "-10" PrintDec EDX, "остаток" ; по выполнении в EDX - "-1" PrintLine PrintText "ДЕЛИМ +4294967551 (FWORD) НА +10 (ECX):" lea EBX, fwordVar ; получаем адрес нулевого байта fwordVar mov EDX, 0 ; обнуляем EDX (два старших байта) mov DX, word ptr [EBX+4] ; посылаем в DX два старших байта fwordVar mov EAX, dword ptr [EBX] ; посылаем в EAX четыре младших байта fwordVar mov ECX, 10 IDIV ECX PrintDec EAX, "частное" ; по выполнении в EAX - "429496755" PrintDec EDX, "остаток" ; по выполнении в EDX - "1" PrintLine PrintText "ДЕЛИМ +4294967551 (QWORD) НА -10 (ECX):" lea EBX, qwordVar ; получаем адрес нулевого байта qwordVar mov EDX, dword ptr [EBX+4] ; посылаем в EDX четыре старших байта qwordVar mov EAX, dword ptr [EBX] ; посылаем в EAX четыре младших байта qwordVar mov ECX, -10 IDIV ECX PrintDec EAX, "частное" ; по выполнении в EAX - "-429496755" PrintDec EDX, "остаток" ; по выполнении в EDX - "1" PrintLine invoke ExitProcess, 0 end start

     


Добавить комментарий

E-mail:
*


Контрольные цифры:

   гость    13.03.2015    23:41
круто. спасибо


   мда    17.11.2015    10:12
ниачем


   Нися    08.11.2016    23:52
Нормуль. Все понял :)


   ROOOOOB1    14.02.2017    14:54
Ваще не понял, не помогло




Ассемблер MASM32

      Простейшая программа на ассемблере (beeper)
      Переменные и типы данных ассемблера
      Регистры процессора IA32
      Консоль ввода-вывода
      API-функция CharToOem и строки ассемблера
      API-функция ReadConsoleInput
      API-функция PeekConsoleInput
      События консоли (таблица)
      Системы счисления, тэги ассемблера, перевод чисел
      Отрицательные числа
      Инкремент и декремент
      Деление (DIV, IDIV)
      VKDEBUG
      Макросы ассемблера
      Воспоминание об Альгамбре на системном динамике
      Командная строка
      Пузырьковая сортировка. Эстафета шариков
      Сортировка расческой
      Быстрая сортировка

     


© Max Petrov При использовании материалов ссылка на sadda.ru обязательна