Система команд x86 |
|
Программирование - Архитектура и система команд микропроцессоров x86 |
SUB
Влияние команды на флаги и форматы команды:
* |
|
|
|
* |
* |
* |
* |
* |
2C ib |
SUB AL,imm8 |
Вычитание imm8 из регистра AL |
8086 |
sub al,0AAh |
2D iw |
SUB AX,imm16 |
Вычитание imm16 из регистра AX |
8086 |
sub ax,0FODh |
2D id |
SUB EAX,imm32 |
Вычитание imm32 из регистра EAX |
Intel386 |
sub eax,23456789h |
80 /5 ib |
SUB r/m8,imm8 |
Вычитание imm8 из r/m8 |
8086 |
sub ah,5 |
81 /5 iw |
SUB r/m16,imm16 |
Вычитание imm16 из r/m16 |
8086 |
sub dx,0DBBh |
81 /5 id |
SUB r/m32,imm32 |
Вычитание imm32 из r/m32 |
Intel386 |
sub edx,0CAAAAh |
83 /5 ib |
SUB r/m16,imm8 |
Вычитание знакорасширенного imm8 из r/m16 |
8086 |
sub cx,0AAh |
83 /5 ib |
SUB r/m32,imm8 |
Вычитание знакорасширенного imm8 из r/m32 |
Intel386 |
sub ecx,02h |
28 /r |
SUB r/m8,r8 |
Вычитание байтового регистра из r/m8 |
8086 |
sub [di],ah |
29 /r |
SUB r/m16,r16 |
Вычитание 16-битного регистра из r/m16 |
8086 |
sub bx,si |
29 /r |
SUB r/m32,r32 |
Вычитание 32-битного регистра из r/m32 |
Intel386 |
sub memory,eax |
2A /r |
SUB r8,r/m8 |
Вычитание r/m8 из байтового регистра |
8086 |
sub dl,sum |
2B /r |
SUB r16,r/m16 |
Вычитание r/m16 из 16-битного регистра |
8086 |
sub di,[si+12] |
2B /r |
SUB r32,r/m32 |
Вычитание r/m32 из 32-битного регистра |
Intel386 |
sub ecx,raznost |
Описание:
Команда SUB (Subtract) относится к группе команд целочисленной (или двоичной) арифметики (Binary Arithmetic Instructions) и производит целочисленное вычитание, вычитая из первого операнда (DEST) второй операнд (SRC) (операнды могут быть знаковыми или беззнаковыми). Первый операнд (операнд-назначение, DEST) может быть переменной в регистре или в памяти (r8, r16, r32, r/m8, r/m16, r/m32). Второй операнд (операнд-источник, SRC) — непосредственным значением (imm8, imm16, imm32), переменной в регистре или в памяти. При этом оба операнда одновременно не могут быть переменными в памяти.
Результат вычитания командой SUB помещается на место первого операнда (DEST). Флаги в регистре EFLAGS устанавливаются в соответствии с полученным результатом.
При вычитании непосредственного значения imm8 или imm16 из двухбайтного или четырехбайтного операнда-источника непосредственная величина прежде всего знакорасширяется до размера первого операнда, и только после этого выполняется вычитание.
Команда SUB позволяет манипулировать целочисленными операндами как в беззнаковом формате, так и в формате со знаком. При вычитании данных со знаком флаг знака EFLAGS.SF будет отражать знак полученного результата. Флаг переполнения EFLAGS.OF установится в 1, если при вычитании целочисленных значений со знаком, представленных в обратном коде или в дополнительном коде, произошло переполнение (заем в старший значащий разряд, которому соответствует бит, предшествующий разряду знака), то есть полученный результат превышает доступный размер операнда-назначения (DEST). По сути, это аналогично тому, как флаг EFLAGS.CF отражает переполнение (заем) при вычитании беззнаковых операндов. Например, при вычитании двух 32-битных значений, представленных в дополнительном коде, это может выглядеть следующим образом:
mov eax, operand1 ; EAX = operand1, первое 32-битное слагаемое помещаем в EAX
sub eax, operand2 ; производим вычитание двух 32-битных операндов в дополнительном коде
into ; переход к обработчику прерывания в случае переполнения
; EAX = operand1 - operand2 - результат вычитания в дополнительном коде
jns m1 ; переход, если результат не отрицательный
not eax
bts eax, 31
inc eax ; преобразование отрицательного значения в EAX к прямому коду
m1: ; EAX - результат вычитания в прямом коде
Флаг вспомогательного (или дополнительного) переноса EFLAGS.AF помогает манипулировать данными в двоично-десятичном формате (упакованный BCD-формат). Он устанавливается, если при вычитании возникает заем в младшую тетраду из старшей тетрады младшего байта результата. Используя команду DAS сразу же вслед за командой SUB, можно произвести так называемую десятичную коррекцию результата вычитания и получить разность в таком же упакованном BCD-формате, как и исходные операнды.
Команда SUB с операндом-назначением (DEST), являющимся переменной в памяти, может использоваться совместно с префиксом блокировки LOCK, который обеспечит атомарное исполнение команды.
Операция:
IF (разрядность SRC меньше разрядности DEST)
THEN DEST = DEST - SignExtend(SRC);
ELSE DEST = DEST - SRC;
FI;
Особые ситуации защищенного режима:
#GP(0), если операнд-назначение (DEST) находится в памяти в сегменте, запрещенном для записи.
#GP(0), если при обращении к операнду в памяти в сегменте DS, ES, FS или GS используется нулевой селектор.
#GP(0), если любая часть операнда в памяти находится вне допустимого пространства эффективных адресов в сегменте CS, DS, ES, FS или GS.
#SS(0), если любая часть операнда в памяти находится вне допустимого пространства эффективных адресов в стековом сегменте SS.
Intel386 … :
#PF(Код ошибки) при страничной ошибке.
#UD при использовании префикса LOCK, если первый операнд команды (DEST) не является значением в памяти.
Intel486 … :
#AC(0) при невыровненной ссылке в память, если активирован контроль выравнивания (CR0.AM = 1, EFLAGS.AC = 1, CPL = 3).
Особые ситуации режима реальной адресации:
#GP, если любая часть операнда в памяти находится вне допустимого для реального режима пространства эффективных адресов в сегменте CS, DS, ES, FS или GS.
#SS, если любая часть операнда в памяти выходит за допустимую для реального режима верхнюю границу стекового сегмента SS.
Intel386 … :
#UD при использовании префикса LOCK, если первый операнд команды (DEST) не является значением в памяти.
Особые ситуации режима V86:
#GP(0), если любая часть операнда в памяти находится вне допустимого пространства эффективных адресов в сегменте CS, DS, ES, FS или GS.
#SS(0), если любая часть операнда в памяти находится вне допустимого пространства эффективных адресов в стековом сегменте SS.
Intel386 … :
#PF(Код ошибки) при страничной ошибке.
#UD при использовании префикса LOCK, если первый операнд команды (DEST) не является значением в памяти.
Intel486 … :
#AC(0) при невыровненной ссылке в память, если активирован контроль выравнивания (CR0.AM = 1, EFLAGS.AC = 1, CPL = 3).
Замечание:
К командам целочисленной арифметики относятся команды ADD, ADC, SUB, SBB, IMUL, MUL, IDIV, DIV, INC, DEC, NEG, CMP.
В свою очередь, сами названные команды целочисленной арифметики делятся на следующие подгруппы:
Все права защищены © Алексей Ровдо, 1994-2023. Перепечатка возможна только по согласованию с владельцем авторских прав. admin@club155.ru