Система команд x86 |
|
Программирование - Архитектура и система команд микропроцессоров x86 |
JMP
Влияние команды на флаги и форматы команды:
|
|
|
|
|
|
|
|
|
EB cb |
JMP rel8 |
Короткий переход, 8-битное знаковое смещение задается относительно следующей команды |
8086 |
E9 cw |
JMP rel16 |
Ближний переход, 16-битное знаковое смещение задается отноcительно следующей команды |
8086 |
E9 cd |
JMP rel32 |
Ближний переход, 32-битное знаковое смещение задается отноcительно следующей команды |
Intel386 |
FF /4 |
JMP r/m16 |
Ближний косвенный переход, r/m16 задает абсолютное смещение адреса назначения |
8086 |
FF /4 |
JMP r/m32 |
Ближний косвенный переход, r/m32 задает абсолютное смещение адреса назначения |
Intel386 |
EA cd |
JMP ptr16:16 |
Дальний межсегментный переход, абсолютный адрес назначения задается 4-байтным непосредственным операндом ptr16:16 |
8086 |
EA cp |
JMP ptr16:32 |
Дальний межсегментный переход, абсолютный адрес назначения задается 6-байтным непосредственным операндом ptr16:32 |
Intel386 |
FF /5 |
JMP m16:16 |
Дальний косвенный межсегментный переход, абсолютный адрес назначения задается 4-байтным операндом в ячейке памяти m16:16 |
8086 |
FF /5 |
JMP m16:32 |
Дальний косвенный межсегментный переход, абсолютный адрес назначения задается 6-байтным операндом в ячейке памяти m16:32 |
Intel386 |
Описание:
Команда JMP передает управление в другую точку потока команд без записи информации о возврате.
Переходы с операндами r/m16, r/m32, rel16 и rel32 называются ближними переходами и не приводят к изменению значения сегментного регистра. Переходы с операндами ptr16:16, ptr16:32, m16:16 и m16:32 называются дальними переходами и предназначены для передачи управления в другой сегмент.
Команды с операндами rel8, rel16 и rel32 используют относительное смещение. В таких командах знаковое смещение (то есть смещение со знаком), представленное в операнде команды перехода, прибавляется к адресу команды, следующей за JMP, а полученная сумма (или разность, если смещение имеет отрицательный знак) определяет абсолютное смещение адреса перехода. Операнд rel16 используется, когда атрибут размера операнда равен 16 бит, rel32 — когда атрибут размера операнда равен 32 бита. Результат сохраняется в 32-битном регистре указателя команд (EIP). В случае rel16, старшие 16 бит регистра EIP очищаются, в результате чего получается смещение, значение которого не превосходит 0x0000FFFFh. Команда с операндом rel8 называется коротким переходом, она имеет самый короткий код операции и может использоваться как при 16-битном размере операнда, так и при 32-битном. Относительное смещение для этой команды может принимать значения от –127 до +128.
Команды JMP r/m16 и JMP r/m32 указывают на регистр или операнд в памяти, откуда выбирается абсолютное смещение адреса назначения. Смещение является 32-битным, в случае 32-битного атрибута размера операнда (r/m32), или 16-битным, в случае 16-битного атрибута размера операнда (r/m16).
Команды JMP ptr16:16 и JMP ptr16:32 называются командами дальнего перехода, они используют четырех- или шести-байтный операнд в качестве длинного указателя на точку назначения. Команды JMP m16:16 и JMP m16:32 выбирают длинный указатель из операнда в памяти (разрешены все режимы адресации). В режиме реальной адресации и в режиме V86 длинный указатель содержит 16 бит для регистра CS и 16 или 32 бита для регистра EIP (в зависимости от атрибута размера операнда). В защищенном режиме обе формы с длинным указателем согласуются с байтом прав доступа (AR) дескриптора, задаваемого селекторной частью длинного указателя. В зависимости от значения этого байта, переход осуществляется с применением одного из следующих типов управляющих преобразований:
- дальний переход в согласованный или несогласованный кодовый сегмент;
- дальний переход через шлюз вызова;
- переключение задачи.
Операция:
IF Ближний переход
THEN
IF Ближний относительный переход (* Смещение задается относительно следующей команды *)
THEN
tempEIP = EIP + DEST; (* EIP указывает на команду, следующую за командой перехода *)
ELSE (* Ближний абсолютный переход *)
tempEIP = DEST;
FI;
IF (tempEIP выходит за границы кодового сегмента) THEN #GP(0); FI;
IF OperandSize = 32
THEN
EIP = tempEIP;
ELSE (* OperandSize=16 *)
EIP = tempEIP AND 0000FFFFH;
FI;
FI;
IF (Дальний переход) AND (PE = 0 OR (PE = 1 AND VM = 1)) (* Режим реальной адресации или V86 *)
THEN
tempEIP = DEST(offset); (* DEST это ptr16:32 или [m16:32] *)
IF (tempEIP выходит за границы кодового сегмента) THEN #GP(0); FI;
CS = DEST(segment selector); (* DEST это ptr16:32 или [m16:32] *)
IF OperandSize = 32
THEN
EIP = tempEIP;
ELSE (* OperandSize = 16 *)
EIP = tempEIP AND 0000FFFFH;
FI;
FI;
IF (Дальний переход) AND (PE = 1 AND VM = 0) (* Защищенный режим, не V86 режим *)
THEN
IF (Операнд m16:16 или m16:32)(* Косвенный переход *)
THEN
Проверка доступности операнда в памяти, #GP(0) при неправильном эффективном адресе;
FI;
Селектор назначения не нулевой, иначе #GP(0);
Индекс селектора назначения должен попадать в пределы таблицы дескрипторов, иначе #GP(Селектор);
Дескриптор, указываемый селектором назначения, может быть дескриптором кодового сегмента, шлюзом вызова, шлюзом задачи или дескриптором TSS, иначе #GP(Селектор назначения);
В зависимости от типа дескриптора назначения:
GO TO CONFORMING-CODE-SEGMENT; (* Согласованный кодовый сегмент *)
GO TO NONCONFORMING-CODE-SEGMENT; (* Несогласованный кодовый сегмент *)
GO TO CALL-GATE; (* Шлюз вызова *)
GO TO TASK-GATE; (* Шлюз задачи *)
GO TO TASK-STATE-SEGMENT; (* TSS - сегмент состояния задачи *)
#GP(Селектор назначения); (* Некорректный AR байт в дескрипторе назначения*)
FI;
CONFORMING-CODE-SEGMENT:
IF DPL > CPL THEN #GP(CS селектор); FI;
Сегмент должен присутствовать, иначе #NP(CS селектор);
tempEIP = DEST(offset);
IF OperandSize = 16
THEN tempEIP = tempEIP AND 0000FFFFH;
FI;
tempEIP должен быть в пределах кодового сегмента, иначе #GP(0);
CS = DEST(SegmentSelector);
CS.RPL = CPL;
EIP = tempEIP;
END;
NONCONFORMING-CODE-SEGMENT:
IF (RPL селектора назначения) > CPL THEN #GP(CS селектор); FI;
IF DPL ¹ CPL THEN #GP(CS селектор);
Сегмент должен присутствовать, иначе #NP(CS селектор);
tempEIP = DEST(offset);
IF OperandSize = 16
THEN tempEIP = tempEIP AND 0000FFFFH;
FI;
tempEIP должен быть в пределах кодового сегмента, иначе #GP(0);
CS = DEST(SegmentSelector);
CS.RPL = CPL;
EIP = tempEIP;
END;
CALL-GATE:
DPL шлюза вызова должен быть ³ CPL, иначе #GP(Селектор шлюза вызова);
DPL шлюза вызова должен быть ³ RPL, иначе #GP(Селектор шлюза вызова);
Шлюз вызова должен присутствовать, иначе #NP(Селектор шлюза вызова);
Проверка селектора кодового сегмента в дескрипторе шлюза вызова:
Селектор должен быть не нулевым, иначе #GP(0);
Индекс селектора должен попадать в пределы таблицы дескрипторов, иначе #GP(CS селектор);
AR байт выбранного дескриптора задает кодовый сегмент, иначе #GP(CS селектор);
IF (Несогласованный кодовый сегмент)
THEN DPL выбранного дескриптора должен быть = CPL, иначе #GP(CS селектор);
FI;
IF (Согласованный кодовый сегмент)
THEN DPL выбранного дескриптора должен быть £ CPL, иначе #GP(CS селектор);
FI;
Сегмент должен присутствовать, иначе #NP(CS селектор);
Указатель инструкции должен быть в пределах кодового сегмента, иначе #GP(0);
tempEIP = DEST(offset);
IF GateSize = 16 (* 16-битный шлюз вызова *)
THEN tempEIP = tempEIP AND 0000FFFFH;
FI;
IF tempEIP не попадает в пределы кодового сегмента THEN #GP(0); FI;
CS = DEST(SegmentSelector);
CS.RPL = CPL;
EIP = tempEIP;
END;
TASK-GATE:
DPL шлюза задачи должен быть ³ CPL, иначе #GP(Селектор шлюза);
DPL шлюза задачи должен быть ³ RPL, иначе #GP(Селектор шлюза);
Шлюз задачи должен присутствовать, иначе #NP(Селектор шлюза);
Проверка селектора TSS в дескрипторе шлюза задачи:
Селектор должен задавать GDT (бит TI=0), иначе #GP(TSS селектор);
Индекс селектора должен попадать в пределы таблицы GDT, иначе #GP(TSS селектор);
AR байт TSS дескриптора должен задавать свободный TSS (младшие биты 00001), иначе #GP(TSS селектор);
TSS должен присутствовать, иначе #NP(TSS селектор);
SWITCH-TASKS (Без вложения) в TSS;
EIP должен быть в пределах кодового сегмента, иначе #GP(0);
END;
TASK-STATE-SEGMENT:
TSS DPL должен быть ³ CPL, иначе #GP(TSS селектор);
TSS DPL должен быть ³ RPL, иначе #GP(TSS селектор);
AR байт TSS дескриптора должен задавать свободный TSS, иначе #GP(TSS селектор);
TSS должен присутствовать, иначе #NP(TSS селектор);
SWITCH-TASKS (С вложением) в TSS;
EIP должен быть в пределах кодового сегмента, иначе #GP(0);
END;
Особые ситуации защищенного режима:
#PF(Код ошибки) при страничной ошибке.
#AC(0) при невыровненной ссылке в память при текущем уровне привилегий равном 3.
Дальние переходы: #GP, #NP, #SS как указано в пункте "Операция".
Ближние прямые переходы: #GP(0), если местоположение точки перехода не попадает в пределы кодового сегмента.
Ближние косвенные переходы: #GP(0), если любая часть операнда находится вне пространства эффективных адресов в сегментах CS, DS, ES, FS или GS; #SS(0), если любая часть операнда находится вне пространства эффективных адресов в сегменте SS.
Особые ситуации режима реальной адресации:
#GP, если любая часть операнда находится вне пространства эффективных адресов от 0 до 0FFFFh.
Особые ситуации режима V86:
Такие же, как и в режиме реальной адресации.
#PF(Код ошибки) при страничной ошибке.
#AC(0) при невыровненной ссылке в память.
Все права защищены © Алексей Ровдо, 1994-2023. Перепечатка возможна только по согласованию с владельцем авторских прав. admin@club155.ru