Код
|
Инструкция
|
Описание
|
77 cb
|
JA rel8
|
Переход, если выше (CF=0 и ZF=0).
|
73 cb
|
JAE rel8
|
Переход, если выше или равно (CF=0).
|
72 cb
|
JB rel8
|
Переход, если ниже (CF=1).
|
76 cb
|
JBE rel8
|
Переход, если ниже или равно (CF=1 или ZF=1).
|
72 cb
|
JC rel8
|
Переход, если есть перенос (CF=1).
|
E3 cb
|
JCXZ rel8
|
Переход, если регистр CX содержит 0.
|
74 cb
|
JE rel8
|
Переход, если равно (ZF=1).
|
7F cb
|
JG rel8
|
Переход, если больше (ZF=0 и SF=OF).
|
7D cb
|
JGE rel8
|
Переход, если больше или равно (SF=OF).
|
7C cb
|
JL rel8
|
Переход, если меньше (SF≠OF).
|
7E cb
|
JLE rel8
|
Переход, если меньше или равно (ZF=1 или SF≠OF).
|
76 cb
|
JNA rel8
|
Переход, если не выше (CF=1 или ZF=1).
|
72 cb
|
JNAE rel8
|
Переход, если не выше или равно (CF=1).
|
73 cb
|
JNB rel8
|
Переход, если не ниже (CF=0).
|
77 cb
|
JNBE rel8
|
Переход, если не ниже или равно (CF=0 и ZF=0).
|
73 cb
|
JNC rel8
|
Переход, если переноса нет (CF=0).
|
75 cb
|
JNE rel8
|
Переход, если не равно (ZF=0).
|
7E cb
|
JNG rel8
|
Переход, если не больше (ZF=1 или SF≠OF).
|
7C cb
|
JNGE rel8
|
Переход, если не больше или равно (SF≠OF).
|
7D cb
|
JNL rel8
|
Переход, если не меньше (SF=OF).
|
7F cb
|
JNLE rel8
|
Переход, если не меньше или равно (ZF=0 и SF=OF).
|
71 cb
|
JNO rel8
|
Переход, если переполнения нет (OF=0).
|
7B cb
|
JNP rel8
|
Переход, если результат нечётный (PF=0).
|
79 cb
|
JNS rel8
|
Переход, если знака нет (SF=0).
|
75 cb
|
JNZ rel8
|
Переход, если не нуль (ZF=0).
|
70 cb
|
JO rel8
|
Переход, если есть переполнение (OF=1).
|
7A cb
|
JP rel8
|
Переход, если результат чётный (PF=1).
|
7A cb
|
JPE rel8
|
Переход, если результат чётный (PF=1).
|
7B cb
|
JPO rel8
|
Переход, если результат нечётный (PF=0).
|
78 cb
|
JS rel8
|
Переход, если есть знак (SF=1).
|
74 cb
|
JZ rel8
|
Переход, если нуль (ZF=1).
|
Первая группа команд условного перехода содержат операнды, которые ставятся после команды сравнения. В их мнемокодах с помощью букв вписывается исход сравнения, при котором следует выполнить переход. Перечислим все обозначения:
E - equal (равно);
N - not (не, отрицание);
Е - greater (больше) для чисел со знаком;
L - less (меньше) для чисел со знаком;
A - above (выше, больше) для чисел без знака;
В - below (ниже, меньше) для чисел без знака.
В табл. 50 приведены названия команд условного перехода, используемых, после команды сравнения. Для условий «меньше» и «больше» введены две системы обозначений. Это связано с тем, что после сравнения чисел со знаком и сравнения чисел без знака нужно реагировать на разные флаги.
В командах, предназначенных для переходов по результатам сравнения чисел со знаком, анализируются флаги SF и OF, а в командах для беззнаковых сравнений – флаг CF. В любом случае равенство или неравенство чисел отражается состоянием флага ZF.
Заметим, что одна и та же команда условного перехода может иметь несколько названий-синонимов. Например, условие «меньше» в то же время является условием «не верно, что больше или равно», поэтому переход «по меньше» для знаковых чисел обозначается и как JL, и как JNGE.
Табл. 50. Мнемокод__Условия_для_перехода_после_CMP_op1,_op2__Состояние_флагов_для_перехода'>Мнемокоды сравнения по команде CMP.
Мнемокод
|
Условия для перехода
после CMP op1, op2
|
Состояние флагов
для перехода
|
Для любых чисел
|
JE
|
op1 = op2
|
ZF=1
|
JNE
|
op1 <> op2
|
ZF=0
|
Для знаковых чисел
|
JL/JNGE
|
op1 < op2
|
SF<>OF
|
JLE/JNG
|
op1 <= op2
|
SF<>OF или ZF=1
|
JG/JNLE
|
op1 > op2
|
SF=OF и ZF=0
|
JGE/JNL
|
op1 >= op2
|
SF=OF
|
Для беззнаковых чисел
|
JB/JNAE
|
op1 < op2
|
CF=1
|
JBE/JNA
|
op1 <= op2
|
CF=1 или ZF=1
|
JA/JNBE
|
op1 > op2
|
CF=0 и ZF=0
|
JAE/JNB
|
op1 >= op2
|
CF=0
|
Рассмотрим пример совместного применения команды сравнения CMP и условного перехода. Пусть необходимо разместить в памяти два числа в порядке возрастания. Для определенности допустим, что числа беззнаковые, размером слово, а смещения их адресов в сегменте данных расположены в регистрах SI и DI.
MOV AX, [SI] ; загрузить в AX первое число
CMP AX, [DI] ; сравнить числа
JBE L ; переход, если первое число меньше либо равно второму
XCHG AX, [DI] ; иначе поменять их местами
MOV [SI], AX ; записать число из AX в ячейку памяти
L:...
Вторая группа команд условного перехода состоит из команд, которые реагируют на значение определенного флага. В мнемокодах команд указывается первый символ проверяемого флага, если переход должен быть выполнен при значении 1 у флага, либо этот символ указывается с символом N (not), если переход требуется сделать при нулевом значении флага (табл. 51). Легко заметить, что следующие пары мнемокодов эквиваленты: JE и JZ, JNE и JNZ, JB и JC, JNB и JNC.
Табл. 51. Мнемокоды сравнения по регистру флагов.
Мнемокод
|
Условие перехода
|
J(N)Z
|
ZF=1(0)
|
J(N)S
|
SF=1(0)
|
J(N)C
|
CF=1(0)
|
J(N)O
|
OF=1(0)
|
J(N)P
|
PF=1(0)
|
Третья группа команд условного перехода содержит всего одну команду, реагирующую на нулевое значение регистра СХ:
JCXZ <метка>
Действие команды JCXZ (jump if CX is zero):
if CX = 0 then goto <метка>
Инструкция JCXZ является единственной командой условного перехода, которая не проверяет состояние флага или группы флагов. Вместо этого она проверяет содержимое регистра CX.
Общая особенность команд условного перехода заключается в том, что команды используют относительную адресацию с 8-разрядным отклонением, что ограничивает длину перехода 127 байтами вперёд и 128 байтами назад относительно адреса команды, следующей за инструкцией перехода (примерно 30-40 команд; в среднем одна команда занимает 3-4 байта). Использовать в командах условного перехода оператор SHORT не имеет смысла, т.к. все переходы короткие.
Для выполнения длинных условных переходов (на расстояние более 127 байтов от команды перехода, а также межсегментных) следует использовать команду длинного безусловного перехода. Например, при длинной метке М оператор:
if AX = BX then goto M
следует реализовывать так:
if AX<>BX then goto L; { короткий переход }
goto M; { длинный переход }
L:...
Ассемблер транслирует ее в следующий код:
CMP АХ, ВХ
JNE L
JMP М
L:...
M:...
Дальние переходы. Все описанные переходы являются ближними. При выполнении ближнего перехода операнд команды содержит новое значение указателя команд IP (смещение следующей выполняемой команды в текущем сегменте кода). Однако в общем случае в программе может быть много команд, и в результате они не поместятся в один сегмент памяти (суммарный размер команд превосходит 64 Кб).
При выполнении дальнего (межсегментного) перехода адрес следующей команды занимает два слова памяти: в первом хранится смещение, во втором – адрес сегмента. Таким образом, команда дальнего перехода загружает регистровую пару CS:IP.
Рассмотрим следующие два сегмента:
C1 SEGMENT
ASSUME CS: C1
START: MOV AX, 0
...
JMP FAR PTR L
C1 ENDS
C2 SEGMENT
ASSUME CS: C2
L: INC BX
...
C2 ENDS
Переход из сегмента C1 на метку L сегмента C2 будет дальним. При таких переходах меняется значение регистра CS и регистра IP: регистр CS настраивается на начало сегмента с меткой CS:=C2, а в регистр IP записывается смещение метки внутри сегмента IP:=OFFSET L.
В системе команд предусмотрены команды, реализующие дальние переходы, причем все они являются только безусловными прямыми или косвенными. В языке ассемблера в этих командах указывается также мнемокод JMP, но с дополнительными операторами. Флаги команды дальнего перехода не меняют:
JMP FAR PTR <метка>
Оператор FAR указывает ассемблеру, что метка дальняя и находится в другом сегменте. По этой команде регистр CS устанавливается на начало того сегмента, в котором находится метка, а в регистр IP записывается смещение метки внутри данного сегмента:
S:=seg <метка:> ; IP:=offset <метка:>
При дальнем косвенном переходе в команде указывается адрес двойного слова, в котором находится адрес перехода в виде адресной пары seg:disp, записанной в обратном порядке: смещение disp должно быть записано по адресу m32, а номер сегмента seg - по адресу m32+2:
JMP m32
Следует заметить, что если X является ссылкой вперед, существуют разновидности команды безусловного перехода:
JMP X ; близкий прямой длинный
JMP SHORT X ; близкий прямой короткий
JMP FAR PTR X ; дальний прямой
JMP WORD PTR X ; близкий косвенный
JMP DWORD PTR X ; дальний косвенный
Такие уточнения требуются и для команды JMP, если указана косвенная ссылка, например JMP [BX]. По умолчанию ассемблер рассматривает подобного рода команду как близкий косвенный переход. Если X – ссылка назад, то вид перехода обязательно следует уточнять только при дальнем прямом переходе. Ассемблер, зная, что X – метка из другого сегмента команд, все равно не будет рассматривать команду JMP X как дальний переход.
Встречая любую метку, ассемблер автоматически приписывает ей тип NEAR (близкий). Операторы NEAR и FAR являются именами стандартных констант со значениями соответственно -1 (0FFFFh) и -2 (0FFFEh).
Do'stlaringiz bilan baham: |