Система команд x86 |
|
Программирование - Архитектура и система команд микропроцессоров x86 |
IDIV
Влияние команды на флаги и форматы команды:
? |
? |
? |
? |
? |
? |
F6 /7 |
IDIV AL,r/m8 |
Деление знаковых AX на r/m8, частное помещается в AL, остаток от деления - в AH |
8086 |
idiv dl |
F7 /7 |
IDIV AX,r/m16 |
Деление знаковых DX:AX на r/m16, частное помещается в AX, остаток от деления - в DX |
8086 |
idiv cx |
F7 /7 |
IDIV EAX,r/m32 |
Деление знаковых EDX:EAX на r/m32, частное помещается в EAX, остаток от деления - в EDX |
Intel386 |
idiv esi |
Описание:
Команда IDIV (Signed Divide) относится к группе команд целочисленной (или двоичной) арифметики (Binary Arithmetic Instructions) и производит целочисленное деление с остатком знаковых целочисленных операндов (для отрицательных значений должен использоваться дополнительный код). Делимое, частное и остаток задаются неявно. Делимое является переменной в регистре (или регистровой паре) AX, DX:AX или EDX:EAX в зависимости от кода команды и атрибута размера операнда (что также определяет и разрядность делителя). Единственный явный операнд команды — операнд-источник (SRC), задающий делитель — может быть переменной в регистре или в памяти (r/m8, r/m16, r/m32). Целая часть частного помещается в регистр AL, AX или EAX в зависимости от заданного размера делителя (8, 16 или 32 бита). При этом остаток от целочисленного деления помещается в регистр AH, DX или EDX соответственно.
Действие команды IDIV зависит от размера операнда-источника (SRC) следующим образом:
Размер |
Делитель |
Частное |
Остаток |
Делимое |
byte |
AL |
AH |
AX |
|
word |
AX |
DX |
DX:AX |
|
dword |
EAX |
EDX |
EDX:EAX |
Если разрядность частного, получаемого в результате деления, оказывается слишком велика, чтобы поместиться в целевом регистре-назначении (то есть имеет место переполнение), или если делитель равен нулю, то генерируется особая ситуация #DE.
Целочисленное частное округляется в сторону нуля. Остаток имеет тот же знак, что и делимое, и абсолютная величина остатка всегда меньше, чем абсолютная величина делителя.
Чтобы предупредить проблемы, вызываемые переполнением, целесообразно увеличивать разрядность делителя командами CBW или CWD, которые должны предшествовать делению IDIV.
Дополнительной особенностью команды IDIV является неопределенное значение большинства флагов в регистре EFLAGS в результате выполнения команды. То есть флаги не устанавливаются в соответствии с полученным частным или остатком.
Для деления целочисленных значений со знаком, кроме команды IDIV, могут также использоваться команды FIDIV и FIDIVR. Команда DIV позволяет выполнять деление целочисленных значений в беззнаковом формате.
Операция:
IF (SRC = 0)
THEN #DE; (* Деление на нуль *)
FI;
IF (OpernadSize = 8) (* Операция "слово/байт" *)
THEN
temp = AX / SRC; (* Знаковое деление *)
IF (temp > 0x7Fh) OR (temp < 0x80h) (* Положительный результат больше 0x7Fh или отрицательный результат меньше чем 0x80h *)
THEN #DE; (* Ошибка деления *)
ELSE
AL = temp;
AH = AX SignedModulus SRC;
FI;
ELSE
IF (OpernadSize = 16) (* Операция "двойное слово/слово" *)
THEN
temp = DX:AX / SRC; (* Знаковое деление *)
IF (temp > 0x7FFFh) OR (temp < 0x8000h) (* Положительный результат больше 0x7FFFh или отрицательный результат меньше чем 0x8000h *)
THEN #DE; (* Ошибка деления*)
ELSE
AX = temp;
DX = DX:AX SignedModulus SRC;
FI;
ELSE (* Операция "учетверенное слово/двойное слово" *)
temp = EDX:EAX / SRC; (* Знаковое деление *)
IF (temp > 0x7FFFFFFFh) OR (temp < 0x80000000h) (* Положительный результат больше 0x7FFFFFFFh или отрицательный результат меньше чем 0x80000000h *)
THEN #DE; (* Ошибка деления *) ;
ELSE
EAX = temp;
EDX = EDXE:AX SignedModulus SRC;
FI;
FI;
FI;
Особые ситуации защищенного режима:
#DE, если делимое равно нулю или частное превышает разрядность регистра-назначения.
#GP(0), если при обращении к операнду в памяти в сегменте DS, ES, FS или GS используется нулевой селектор.
#GP(0), если любая часть операнда в памяти находится вне допустимого пространства эффективных адресов в сегменте CS, DS, ES, FS или GS.
#SS(0), если любая часть операнда в памяти находится вне допустимого пространства эффективных адресов в стековом сегменте SS.
Intel386 … :
#PF(Код ошибки) при страничной ошибке.
#UD при использовании префикса LOCK.
Intel486 … :
#AC(0) при невыровненной ссылке в память, если активирован контроль выравнивания (CR0.AM = 1, EFLAGS.AC = 1, CPL = 3).
Особые ситуации режима реальной адресации:
#DE, если делимое равно нулю или частное превышает разрядность регистра-назначения.
#GP, если любая часть операнда в памяти находится вне допустимого для реального режима пространства эффективных адресов в сегменте CS, DS, ES, FS или GS.
#SS(0), если любая часть операнда в памяти выходит за допустимую для реального режима верхнюю границу стекового сегмента SS.
Особые ситуации режима V86:
#DE, если делимое равно нулю или частное превышает разрядность регистра-назначения.
#GP(0), если любая часть операнда в памяти находится вне допустимого пространства эффективных адресов в сегменте CS, DS, ES, FS или GS.
#SS(0), если любая часть операнда в памяти находится вне допустимого пространства эффективных адресов в стековом сегменте SS.
Intel386 … :
#PF(Код ошибки) при страничной ошибке.
#UD при использовании префикса LOCK.
Intel486 … :
#AC(0) при невыровненной ссылке в память, если активирован контроль выравнивания (CR0.AM = 1, EFLAGS.AC = 1, CPL = 3).
Замечание:
Отдельные особенности существовали у процессоров 8086/8088 для генерации особой ситуации деления на нуль (#DE). В этих процессорах, в отличие от последующих моделей, точка возврата CS:IP, сохраняемая в стеке, не указывает на команду IDIV, вызвавшую прерывание, — она указывает на следующую за ней команду. Кроме того, в процессорах 8086/8088 частное от деления не может быть наименьшим отрицательным числом (-128 для байта, - 32768 для слова и -231 для двойного слова) — в таком случае генерируется особая ситуация деления на нуль (#DE) как для переполнения. А вот в более поздних моделях процессоров указанные значения для частного допустимы и особой ситуации не возникает.
К командам целочисленной арифметики относятся команды ADD, ADC, SUB, SBB, IMUL, MUL, IDIV, DIV, INC, DEC, NEG, CMP.
В свою очередь, сами названные команды целочисленной арифметики делятся на следующие подгруппы:
Все права защищены © Алексей Ровдо, 1994-2023. Перепечатка возможна только по согласованию с владельцем авторских прав. admin@club155.ru