Флаги состояния и условные переходы
Последнее обновление: 01.07.2023
Также в ассемблере есть ряд инструкций, которые выполняют условные переходы в зависимости от установки битов в регистре FLAGS. В частности,
учитываются четыре бита — carry (флаг переноса), overflow (флаг переполнения), sign (флаг знака) и zero (флаг нуля):
-
CF (флаг переноса): устанавливается, если происходит беззнаковое переполнение, то есть при сумме с переносом или вычитании с заимствованием (например, при сумме чисел 0FFh и 01h).
Если переполнение не происходит, то флаг не устанавливается. -
OF (флаг переполнения): установливается, если происходит переполнение со знаком, а именно когда переполняется бит, следующий за старшим
знаковым битом. Например, при сумме чисел 7Fh и 01h. В двоичной системе это будет операция0111 1111 + 0000 0001
, результатом которой формально
будет число1000 0000
. Таким образом, произошло изменение старшего знакового бита. -
SF (флаг знака): устанавливается, если старший бит результата установлен. В противном случае флаг знака сброшен
(то есть флаг знака отражает состояние старшего бита результата). -
ZF (флаг нуля): устанавливается, если результат вычисления дает 0. Если результат ненулевой, флаг сброшен
Эти флаги устанавливаются в результате различных операций. В частности, инструкции add, sub, and, or,
xor и not влияют на установку флагов. А mov или lea не влияют.
Для проверки этих флагов и выполнения условного перехода в ассемблере есть следующие инструкции:
-
jc: выполняет переход к метке, если флаг переноса установлен
-
jnc: выполняет переход к метке, если флаг переноса НЕ установлен
-
jo: выполняет переход к метке, если флаг переполнения установлен
-
jno: выполняет переход к метке, если флаг переполнения не установлен
-
js: выполняет переход к метке, если флаг знака установлен
-
jns: выполняет переход к метке, если флаг знака не установлен
-
jz: выполняет переход к метке, если флаг нуля установлен
-
jnz: выполняет переход к метке, если флаг нуля не установлен
Все эти инструкции принимают один операнд — метку, к которой выполняется переход. Например:
.data n1 dword 0FFFFFFFFh n2 dword 1h .code main proc mov eax, n1 add eax, n2 jc overflow mov eax, 0 ret overflow: mov eax, 1 ret main endp end
Здесь в регистр EAX загружаем число n1, которое равно 0FFFFFFFFh. Затем с помощью инструкции add
складываем его с число n2, которое равно 0.
mov eax, n1 add eax, n2
Если произошел перенос, то устанавливается флаг переноса. С помощью инструкции:
jc overflow
Проверям, имеет ли место перенос. И если есть переполнение, и соответственно флаг переноса установлен в 1, то выполняем переход к метке overflow. Если флаг переноса НЕ установлен,
то выполняем последующие инструкции — в регистр EAX помещаем число 0 и выходим из процедуры:
mov eax, 0 ret
Если флаг установлен, то переходим к метке overflow и в регистр EAX помещаем число 0 и выходим из процедуры:
overflow: mov eax, 1 ret
В данном случае поскольку при сложении чисел 0FFFFFFFFFh и 1 результат будет равен 100000000h, соответственно будет выполняться перенос, то будет происходить переход к метке overflow,
а в регистре EAX окажется число 1.
Наконец-то мы добрались и до переходов! В этой части научимся программировать условные и безусловные переходы. Вообще, трудно представить себе программу без проверки условий и переходов. С их помощью в программе реализуются различные управляющие конструкции, ветвления и даже циклы.
Безусловные переходы
Безусловный переход — это переход, который выполняется всегда. Безусловный переход осуществляется с помощью команды JMP. У этой команды один операнд, который может быть непосредственным адресом (меткой), регистром или ячейкой памяти, содержащей адрес. Существуют также «дальние» переходы — между сегментами, однако здесь мы их рассматривать не будем. Примеры безусловных переходов:
jmp metka ;Переход на метку jmp bx ;Переход по адресу в BX jmp word[bx] ;Переход по адресу, содержащемуся в памяти по адресу в BX
Условные переходы
Условный переход осуществляется, если выполняется определённое условие, заданное флагами процессора (кроме одной команды, которая проверяет CX на равенство нулю). Как вы помните, состояние флагов изменяется после выполнения арифметических, логических и некоторых других команд. Если условие не выполняется, то управление переходит к следующей команде.
Существует много команд для различных условных переходов. Также для некоторых команд есть синонимы (например, JZ и JE — это одно и то же). Для наглядности все команды условных переходов приведены в таблице:
Команда | Переход, если | Условие перехода |
---|---|---|
JZ/JE | нуль или равно | ZF=1 |
JNZ/JNE | не нуль или не равно | ZF=0 |
JC/JNAE/JB | есть переполнение/не выше и не равно/ниже | CF=1 |
JNC/JAE/JNB | нет переполнения/выше или равно/не ниже | CF=0 |
JP | число единичных бит чётное | PF=1 |
JNP | число единичных бит нечётное | PF=0 |
JS | знак равен 1 | SF=1 |
JNS | знак равен 0 | SF=0 |
JO | есть переполнение | OF=1 |
JNO | нет переполнения | OF=0 |
JA/JNBE | выше/не ниже и не равно | CF=0 и ZF=0 |
JNA/JBE | не выше/ниже или равно | CF=1 или ZF=1 |
JG/JNLE | больше/не меньше и не равно | ZF=0 и SF=OF |
JGE/JNL | больше или равно/не меньше | SF=OF |
JL/JNGE | меньше/не больше и не равно | SF≠OF |
JLE/JNG | меньше или равно/не больше | ZF=1 или SF≠OF |
JCXZ | содержимое CX равно нулю | CX=0 |
У всех этих команд один операнд — имя метки для перехода. Обратите внимание, что некоторые команды применяются для беззнаковых чисел, а другие — для чисел со знаком. Сравнения «выше» и «ниже» относятся к беззнаковым числам, а «больше» и «меньше» — к числам со знаком. Для беззнаковых чисел признаком переполнения будет флаг CF, а соответствующими командами перехода JC и JNC. Для чисел со знаком о переполнении можно судить по состоянию флага OF, поэтому им соответствуют команды перехода JO и JNO. Команды переходов не изменяют значения флагов.
В качестве примера я приведу небольшую программу для сложения двух чисел со знаком с проверкой переполнения. В случае переполнения будет выводиться сообщение об ошибке. Вы можете поменять значения объявленных переменных, чтобы переполнение возникало или не возникало при их сложении, и посмотреть, что будет выводить программа.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
use16 ;Генерировать 16-битный код org 100h ;Программа начинается с адреса 100h mov al,[x] ;AL = x add al,[y] ;AL = x + y jo error ;Переход, если переполнение mov ah,09h ;\ mov dx,ok_msg ; > Вывод строки 'OK' int 21h ;/ exit: mov ah,09h ;\ mov dx,pak ; > Вывод строки 'Press any key...' int 21h ;/ mov ah,08h ;\ int 21h ;/ Ввод символа mov ax,4C00h ;\ int 21h ;/ Завершение программы error: mov ah,09h ;\ mov dx,err_msg ; > Вывод сообщения об ошибке int 21h ;/ jmp exit ;Переход на метку exit ;---------------------------------------------------------- x db -89 y db -55 err_msg db 'Error: overflow detected.',13,10,'$' ok_msg db 'OK',13,10,'$' pak db 'Press any key...$' |
Команды CMP и TEST
Часто для формирования условий переходов используются команды CMP и TEST. Команда CMP предназначена для сравнения чисел. Она выполняется аналогично команде SUB: из первого операнда вычитается второй, но результат не записывается на место первого операнда, изменяются только значения флагов. Например:
cmp al,5 ;Сравнение AL и 5 jl c1 ;Переход, если AL < 5 (числа со знаком)
cmp al,5 ;Сравнение AL и 5 jb c1 ;Переход, если AL < 5 (числа без знака)
Команда TEST работает аналогично команде AND, но также результат не сохраняется, изменяются только флаги. С помощью этой команды можно проверить состояние различных битов операнда. Например:
test bl,00000100b ;Проверить состояние 2-го бита BL jz c2 ;Переход, если 2-й бит равен 0
Пример программы
Простая программка, которая выводит меню и предлагает пользователю сделать выбор. Для ввода символа используется функция DOS 01h (при вводе символ отображается на экране). В зависимости от введённого символа осуществляется переход на нужный кусок кода. Для разнообразия, я поместил данные в начале программы, а не в конце (кстати, обычно так и делают). Чтобы данные не выполнились как код, перед ними стоит команда безусловного перехода.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
use16 ;Генерировать 16-битный код org 100h ;Программа начинается с адреса 100h jmp start ;Безусловный переход на метку start ;---------------------------------------------------------- menu db '1 - Print hello',13,10 db '2 - Print go away',13,10 db '0 - Exit',13,10,'$' select db 13,10,'Select>$' hello db 13,10,'Hello!',13,10,13,10,'$' go_away db 13,10,'Go away!',13,10,13,10,'$' ;---------------------------------------------------------- start: mov ah,09h ;\ mov dx,menu ; > Вывод меню int 21h ;/ select_loop: mov ah,09h ;\ mov dx,select ; > Вывод строки 'Select>' int 21h ;/ mov ah,01h ;Функция DOS 01h - ввод символа int 21h ;Введённый символ помещается в AL cmp al,'1' ;Сравнение введённого символа с '1' je c1 ;Переход, если равно cmp al,'2' ;Сравнение введённого символа с '2' je c2 ;Переход, если равно cmp al,'0' ;Сравнение введённого символа с '0' je exit ;Переход, если равно jmp select_loop ;Безусловный переход c1: mov ah,09h ;\ mov dx,hello ; > Вывод строки 'Hello' int 21h ;/ jmp start ;Безусловный переход c2: mov ah,09h ;\ mov dx,go_away ; > Вывод строки 'Go away' int 21h ;/ jmp start ;Безусловный переход exit: mov ax,4C00h ;\ int 21h ;/ Завершение программы |
Скриншот работы программы:
Упражнение
Упражнение простое. Напишите программу для сравнения двух переменных со знаком a и b. В зависимости от результатов сравнения выведите «a < b», «a > b» или «a = b». Проверьте работу программы в отладчике. Результаты можете выкладывать в комментариях.
Следующая часть »
Команды условных переходов
Команды условных
переходов передают управление в
зависимости от значения некоторого
условия. Они записываются в формате:
Jcond Labl,
где cond
формальное условие перехода,и передают
управление по метке Labl в случае истинности
заданного условия. В противном случае
выполняется очередная команда программы.
Все условные
переходы являются короткими (тип SHORT).
Это обусловлено тем, что в машинном коде
команд условных переходов лишь один
байт выделен для хранения дистанции
disp8 до метки, который и используется для
вычисления адреса перехода
(IP)=(IP)+disp8(Labl). Отсюда любая команда
условного перехода передает управление
в пределах от (128)
до (+127) байтов.
Большинство
команд условных переходов имеют две
мнемоники. Выбор той или иной мнемоники
позволяет подчеркнуть смысл проверяемого
условия перехода и сделать программу
более понятной.
Команды условных
переходов могут передавать управление
в зависимости от различных условий. Все
они могут быть разделены на следующие
подгруппы:
1) команды перехода
по состоянию арифметических флагов;
2) команды перехода
по соотношению между числами;
3) команды перехода
по состоянию регистра CX.
Команды перехода по состоянию арифметических флагов
Команды этой
подгруппы используют в качестве условия
перехода состояние арифметических
флагов. При этом проверяемое условие
перехода cond может принимать следующие
фактические значения:
Z/E
нуль/равно (ZF=1), NZ/NE
не нуль/не равно (ZF=0),
C
наличие переноса (CF=1), NC
отсутствие переноса (CF=0),
S
отрицательный результат (SF=1), NS
положительный результат (SF=0),
P/PE
четный паритет (PF=1), NP/PO
нечетный паритет (PF=0),
O
наличие переполнения (OF=1), NO
отсутствие переполнения (OF=0).
Здесь через
дробную черту приведены альтернативные
названия одного и того же условия.
Таким образом,
команды условного перехода по состоянию
арифметических флагов в зависимости
от проверяемого условия могут записываться
в следующем виде: JZ/JE, JNZ/JNE; JC, JNC; JS, JNS;
JP/JPE, JNP/JPO; JO, JNO.
Эти команды могут
использоваться после любой команды,
формирующей соответствующий флаг.
Пример 3.93:
DEC CL
JNZ Begin ; Переход,
если (CL) не нуль
. . . . . . . . .
ADD AX, Word ; Сложение
знаковых чисел
JO Overflow ; Переход,
если переполнение
Команды перехода по соотношению между числами
Команды этой
подгруппы используются только после
команды сравнения CMP. В результате
сравнения формируются флаги, позволяющие
проверить все соотношения между числами.
Однако, рассматриваемые команды реализуют
операторы отношений <, >, < =, > =.
Для анализа
результатов сравнения беззнаковых и
знаковых чисел служат различные команды
условного перехода. Это обусловлено
тем, что использование дополнительного
кода для представления знаковых чисел
вносит существенное различие в
интерпретацию результатов сравнения
чисел без знака и со знаком.Например,
код FFh=11111111b как число без знака имеет
значение 255>0, а как число со знаком
(1)<0.
Для устранения
этой путаницы при сравнении беззнаковых
чисел используются термины «ниже»
(Below) »выше»
(Above), а при сравнении чисел со знаком
«меньше» (Less)
«больше» (Greater), выбор которых
поясняется рис.3.6.
Рис. 3.6. Числовые
оси для представления чисел
В соответствии
с этим формальное условие cond команд
условных переходов по соотношению между
беззнаковыми числами может принимать
следующие фактические значения:
B/NAE
ниже/не выше и не равно, NB/AE
не ниже/выше или равно, BE/NA
ниже или равно/не выше, NBE/A
не ниже и не равно /выше.
Отсюда команды
условных переходов по соотношению между
беззнаковыми числами имеют вид: JB/JNAE,
JNB/JAE, JBE/JNA, JNBE/JA.
Аналогично условие
cond команд условных переходов по
соотношению между знаковыми числами
может принимать значения:
L/NGE
меньше/не больше и не равно, NL/GE
не меньше/больше или равно,
LE/NG
меньше или равно/не больше, NLE/G
не меньше и не равно/
/больше.
Отсюда команды
условных переходов по соотношению между
знаковыми числами имеют вид: JL/JNGE,
JNL/JGE, JLE/JNG, JNLE/JG.
На практике для
выбора команды условного перехода,
следующей за командой сравнения (CMP
приемник, источник), используется табл.
3.3.
Таблица 3.3
Выбор команд
условных переходов в сочетании с командой
CMP
-
Условие
переходаСледующая
за CMP командадля
чисел без знакадля
чисел со знакомПриёмник
> источникJA/JNBE
JG/JNLE
Приёмник
= источникJE
JE
Приёмник
< > источникJNE
JNE
Приёмник
< источникJB/JNAE
JL/JNGE
Приёмник
< = источникJBE/JNA
JLE/JNG
Приёмник
> = источникJAE/JNB
JGE/JNL
Для анализа
операндов на равенство, то есть для
реализации операторов отношений = и <
>, необходимо использовать команды JE
и JNE из первой подгруппы. В этом случае
нет различий в сравнении знаковых и
беззнаковых чисел.
Пример 3.94:
Реализовать
ветвление программы в зависимости от
соотношения между знаковым числом
из регистра AL и числом 100.
CMP AL, 100 ;
Сравнение (AL) с числом 100
JGE GE100 ; Переход,
если (AL)>=100
. . . . . . . . ;
Команды для выполнения при (AL)<100
GE100: JG
G100 ; Переход, если (AL)>100
. . . . . . .
. ; Команды для выполнения при (AL)=100
G100: .
. . . . . . . ; Команды для выполнения при
(AL)>100
Соседние файлы в папке Микропроцессорные системы (книга Комаров)
- #
08.03.201578.74 Кб55KUDRIASH.TTF
- #
- #
- #
- #
- #
- #
- #
- #
- #
- #
Логика и организация программы
На прошлом уроке для того, чтобы сделать задержку и считать символ с клавиатуры, мы были вынуждены использовать цикл. Сегодня мы более подробно познакомимся с непоследовательным выполнением команд. Большинство программ содержат ряд циклов, в которыхнесколько команд повторяются до достижения определенного
требования, и различные проверки, определяюшие, какие из
нескольких действий следует выполнять. Обычным требованием
является проверка — должна ли программа завершить
выполнение. Эти требования включают передачу управления по адресу
команды, которая не находится непосредственно за выполняемой
в текущий момент командой. Передача управления может осуществляться вперед для выполнения новой группы команд или назад
для повторения уже выполненных команд.
Некоторые команды могут передавать управление, изменяя
нормальную последовательность шагов непосредственной
модификацией значения смещения в командном указателе. Ниже
приведены четыре способа передачи управления (все будут
рассмотрены в этой главе):
Безусловный переход: JMP Цикл: LOOP Условный переход: Jnnn (больше,меньше,равно) Вызов процедуры: CALL
Заметим, что имеется три типа адресов: SHORT, NEAR и FAR.
Адресация SHORT используется при циклах, условных пеpеходах
и некоторых безусловных переходах. Адресация NEAR и FAR
используется для вызовов процедур (CALL) и безусловных
переходов, которые не квалифицируются , как SHORT. Все три
типа передачи управления воздействуют на содержимое регистра
IP; тип FAR также изменяет регистр CS.
Команда JMP
Одной из команд, обычно используемых для передачи управле
ния является команда JMP. Эта команда выполняет безусловный
переход, т.е. обеспечивает передачу управления при любых
обстоятельствах. Команда JMP для перехода в пределах -128 до +127 байт
имеет тип SHORT. Ассемблер генерирует в этом случае
однобайтовый операнд в пределах от 00 до FF. Команда JMP,
превосходящая эти пределы, получает тип FAR, для которого
генерируется другой машинный код и двухбайтовый операнд.
Ассемблер в первом просмотре исходной программы определяет
длину каждой команды. Однако, команда JMP может быть длиной
два или три байта. Если к моменту просмотра команды JMP
ассемблер уже вычислил значение опеpанда (при переходе
назад):
A50: ... JMP A50
то он генерирует двухбайтовую команду. Если ассемблер еще не
вычислил значение операнда (при переходе вперед)
JMP A90 ... A90:
то он не знает тип перехода NEAR или FAR, и автоматически
генерирует 3-х байтовую команду. Для того, чтобы указать
ассемблеру на необходимость генерации двухбайтовой команды,
следует использовать оператор SHORT:
JMP SHORT A90 ... A90:
В качестве полезного упражнения, введите программу,
проассемблируйте ее, скомпануйте и переведите в COM-формат.
Определение данных не требуется, поскольку непосредственные
операнды генерируют все необходимые данные. Используйте
отладчик DEBUG для пошагового выполнения COM-модуля и
просмотрите несколько повторений цикла. Когда регистр AX
будет содержать 08, BX и CX увеличатся до шест. 24 (дес.
36) и шест. 80 (дес. 128), соответственно. Для выхода из
отладчика используйте команду Q.
команда LOOP
Команда JMP в примере на рис. 7.1 реализует бесконечный
цикл. Но более вероятно подпрограмма должна выполнять
определенное число циклов. Команда LOOP, которая служит для
этой цели, использует начальное значение в регистре CX. В
каждом цикле команда LOOP автоматически уменьшает содержимое
регистра CX на 1. Пока значение в CX не равно нулю,
управление передается по адресу, указанному в операнде, и
если в CX будет 0, управление переходит на слудующую после
LOOP команду.
Аналогично команде JMP, операнд команды LOOP определяет
расстояние от конца команды LOOP до адреса метки A20, кото
рое прибавляется к содержимому командного указателя. Для
команды LOOP это расстояние должно быть в пределах от -128
до +127 байт. Если операнд превышает эти границы, то ассемб
лер выдаст сообщение «Relative jump out of range» (превышены
границы перехода).
Дополнительно существует две разновидности команды LOOP —
это LOOPE (или LOOPZ) и LOOPNE (или LOOPNZ). Обе команды
также уменьшают значение регистра CX на 1. Команда LOOPE
передает управление по адресу операнда, если регистр CX
имеет ненулевое значение и флаг нуля установлен (ZF=1).
Команда LOOPNE передает управление по адресу операнда, если
регистр CX имеет ненулевое значение и флаг нуля сброшен
(ZF=0).
Регистр флагов (Flags)
Следующий материал данной главы требует более детального
ознакомления с флаговым регистром. Этот pегистр содержит 16
бит флагов, которые управляются различными командами для
индикации состояния операции. Во всех случаях флаги сохраня
ют свое значение до тех пор, пока другая команда не изменит
его. Флаговый регистр содержит следующие девять используемых
бит (звездочками отмечены неиспользуемые биты):
Номер бита: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 Флаг: * * * * O D I T S Z * A * P * C
Рассмотрим эти флаги в последовательности справа налево.
CF (Carry Flag)
флаг переноса. Содержит значение
«переносов» (0 или 1) из старшего разряда при арифметичес
ких операциях и некоторых операциях сдвига и циклического
сдвига (см. гл.12).
PF (Parity Flag)
флаг четности. Проверяет младшие
восемь бит pезультатов операций над данными. Нечетное число
бит приводит к установке этого флага в 0, а четное — в 1. Не
следует путать флаг четности с битом контроля на четность.
AF (Auxiliary Carry Flag)
дополнительный флаг переноса.
Устанавливается в 1, если арифметическая операция приводит
к переносу четвертого бита справа (бит номер 3) в регистро
вой однобайтовой команде. Данный флаг имеет отношение к
арифметическим операциям над символами кода ASCII и к
десятичным упакованным полям.
ZF (Zero Flag)
флаг нуля. Устанавливается в качестве
результата aрифметических команд и команд сравнения. Как
это ни странно, ненулевой результат приводит к установке
нулевого значения этого флага, а нулевой — к установке
единичного значения. Кажущееся несоответствие является,
однако, логически правильным, так как 0 обозначает «нет»
(т.е. результат не равен нулю), а единица обозначаeт «да»
(т.е. результат равен нулю). Команды условного перехода JE и
JZ проверяют этот флаг.
SF (Sign Flag)
знаковый флаг. Устанавливается в соответ
ствии со знаком результата (старшего бита) после арифмети
ческих опеpаций: положительный результат устанавливает 0, а
отрицательный — 1. Команды условного перехода JG и JL
проверяют этот флаг.
TF (Trap Flag)
флаг пошагового выполнения. Этот флаг
вам уже приходилось устанавливать, когда использовалась ко
манда Т в отладчике DEBUG. Если этот флаг установлен в еди
ничное cостояние, то процессор переходит в режим пошагового
выполнения команд, т.е. в каждый момент выполняется одна
команда под пользовательским управлением.
IF (Interrupt Flag)
флаг прерывания. При нулевом состоя
нии этого флага прерывания запрещены, при единичном —
разрешены.
DF (DIrection Flag)
флаг направления. Используется в
строковых операциях для определения направления передачи
данных. При нулевом состоянии команда увеличивает содержимое
регистров SI и DI, вызывая передачу данных слева направо,
при нулевом — уменьшает содержимое этих регистров, вызывая
передачу данных справа налево.
OF (Overflow Flag)
флаг переполнения. Фиксирует арифме
тическое переполнение, т.е. перенос в/из старшего (знаково
го) бита при знаковых арифметических операциях.
В качестве примера: команда CMP сравнивает два операнда
и воздействуте на флаги AF, CF, OF, PF, SF, ZF. Однако, нет
необходимости проверять все эти флаги по отдельности. В сле-
дующем примере проверяется содержит ли регистр BX нулевое
значение:
CMP BX,00 ;Сравнение BX с нулем JZ B50 ;Переход на B50 если нуль . (действия при ненуле) . B50: ... ;Точка перехода при BX=0
Если BX содержит нулевое значение, команда CMP устанавливает
флаг нуля ZF в единичное состояние, и возможно изменяет (или
нет) другие флаги. Команда JZ (перехлд если нуль) проверяет
только флаг ZF. При единичном значении ZF, обозначающее
нулевой признак, команда передает управление на адрес,
указанный в ее операнде, т.е. на метку B50.
В предыдущих примерах было показано, что команда LOOP
уменьшает на единицу содержимое регистра CX и проверяет его:
если не ноль, то управление передается по адресу, указанному
в операнде. Таким образом, передача управления зависит от
конкретного состояния. Ассемблер поддерживает большое
количество команд условного перехода, которые осуществляют
передачу управления в зависимости от состояний флагового
регистра. Например, при сравнении содержимого двух полей
последующий переход зависит от значения флага.
Команду LOOP в программе на рис.7.2 можно заменить на две
команды: одна уменьшает содержимое регистра CX, а другая
выполняет условный переход:
Использование LOOP Использование условного перехода
LOOP A20 DEC CX JNZ A20
Команды DEC и JNZ действуют аналогично команде LOOP:
уменьшают содержимое регистра CX на 1 и выполняет переход на
метку A20, если в CX не ноль. Команда DEC кроме того
устанавливает флаг нуля во флаговом регистре в состояние 0
или 1. Команда JNZ затем проверяет эту установку. В рассмот
ренном примере команда LOOP хотя и имеет огпаниченное исполь
зование, но более эффективна, чем две команды: DEC и JNZ.
Аналогично командам JMP и LOOP операнд в команде JNZ
cодержит значение расстояния между концом команды JNZ и
адресом A20, которое прибавляется к командному указателю.
Это расстояние должно быть в пределах от -128 до +127 байт.
В случае перехода за эти границы ассемблер выдаст сообщение
«Relative jump out of range» (превышены относительные грани
цы перехода).
Знаковые и беззнаковые данные
Рассматривая назначение команд условного перехода следует
пояснить характер их использования. Типы данных, над которы
ми выполняются арифметические операции и операции сравнения
определяют какими командами пользоваться: беззнаковыми или
знаковыми. Беззнаковые данные используют все биты как биты
данных; характерным примером являются символьные строки:
имена, адреса и натуральные числа. В знаковых данных самый
левый бит представляет собой знак, причем если его значение
равно нулю, то число положительное, и если единице, то
отрицательное. Многие числовые значения могут быть как
положительными так и отрицательными.
В качестве примера предположим, что регистр AX содержит
11000110, а BX — 00010110. Команда
CMP AX,BX
сравнивает содержимое регистров AX и BX. Если данные
беззнаковые, то значение в AX больше, а если знаковые — то
меньше.
Условные переходы
Переходы для беззнаковых данных
Мнемоника Описание Проверяемые флаги
JE/JZ Переход, если равно/нуль ZF JNE/JNZ Переход, если не равно/не нуль ZF JA/JNBE Переход, если выше/не ниже или равно ZF,CF JAE/JNB Переход, если выше или равно/не ниже CF JB/JNAE Переход, если ниже/не выше или равно CF JBE/JNA Переход, если ниже или равно/не выше CF,AF
Любую проверку можно кодировать одним из двух мнемоничес
ких кодов. Например, JB и JNAE генерирует один и тот же
объектный код, хотя положительную проверку JB легче понять,
чем отрицательную JNAE.
Переходы для знаковых данных
Мнемоника Описание Проверяемые флаги
JE/JZ Переход, если равно/нуль ZF JNE/JNZ Переход, если не равно/не нуль ZF JG/JNLE Переход, если больше/не меньше или равно ZF,SF,OF JGE/JNL Переход, если больше или равно/не меньше SF,OF JL/JNGE Переход, если меньше/не больше или равно SF,OF JLE/JNG Переход, если меньше или равно/не больше ZF,SF,OF
Команды перехода для условия равно или ноль (JE/JZ) и не
равно или не ноль (JNE/JNZ) присутствуют в обоих списках
для беззнаковых и знаковых данных. Состояние равно/нуль
происходит вне зависимости от наличия знака.
Специальные арифметические проверки
Мнемоника Описание Проверяемые флаги
JS Переход, если есть знак (отрицательно) SF JNS Переход, если нет знака(положительно) SF JC Переход, если есть перенос (аналогично JB) CF JNC Переход, если нет переноса CF JO Переход, если есть переполнение OF JNO Переход, если нет переполнения OF JP/JPE Переход, если паритет четный PF JNP/JP Переход, если паритет нечетный PF
Еще одна команда условного перехода проверяет равно ли
содержимое регистра CX нулю. Эта команда необязательно
должна pасполагаться непосредственно за командой арифметики
или сравнения. Одним из мест для команды JCXZ может быть
начало цикла, где она проверяет содержит ли регистр CX
ненулевое значение.
Не спешите пока заучивать эти команды наизусть. Запомните
только, что для беззнаковых данных есть переходы по состоя
ниям равно, выше или ниже, а для беззнаковых — равно,
больше или меньше. Переходы по проверкам флагов переноса,
переполнения и паритета имеют особое назначение. Ассемблер
транслирует мнемонические коды в объектный код независимо
от того, какую из двух команд вы применили. Однако, команды
JAE и JGE являясь явно одинаковыми, проверяют различные
флаги.
I am trying to find online the usage of the assembly language function «je». I read that je means jump if equal and that is exactly what I want. What is the actual usage of this function, or in other words, how to I type this function to check a value and jump if it is equal to something?
Please let me know.
BTW, I am using NASM if that makes a difference.
asked Oct 17, 2009 at 19:04
Let’s say you want to check if EAX
is equal to 5
, and perform different actions based on the result of that comparison. An if-statement, in other words.
; ... some code ...
cmp eax, 5
je .if_true
; Code to run if comparison is false goes here.
jmp short .end_if
.if_true:
; Code to run if comparison is true goes here.
.end_if:
; ... some code ...
answered Oct 17, 2009 at 19:14
bcatbcat
8,8433 gold badges35 silver badges41 bronze badges
2
I have to say je func is to test if zero flag is set and then jump to somewhere else or continue to the next instruction that follows.
test cx, cx
je some_label
The test instruction just does a bitwise AND of the two operands, and set the FLAG according to the AND result. The je instruction then uses the ZERO flag to decide to jump or continue.
The code above is used to check if cx is zero or not.
- If cx is zero, test will set zero flag, then je will cause to jump to some place;
- If cx is not zero, test will not set zero flag, je will continue to execute the instruction that follows.
NOTE: je is not to test equal, but to test the ZERO flag which is set by some instruction before this.
Cosmin
21.2k5 gold badges45 silver badges60 bronze badges
answered May 25, 2011 at 3:40
wljackherowljackhero
1511 silver badge2 bronze badges
This will jump if the «equal flag» (also known as the «zero flag») in the FLAGS
register is set. This gets set as a result of arithmetic operations, or instructions like TEST
and CMP
.
For example: (if memory serves me right this is correct
cmp eax, ebx ; Subtract EBX from EAX -- the result is discarded ; but the FLAGS register is set according to the result. je .SomeLabel ; Jump to some label if the result is zero (ie. they are equal). ; This is also the same instruction as "jz".
answered Oct 17, 2009 at 19:11
asveikauasveikau
39.1k2 gold badges53 silver badges68 bronze badges
You’ll precede the je
with a cmp
(or test
or equivalent) usually, which sets a flag in the EFLAGS register. Here’s a link to a simple echo server in NASM that might help in general. Ignore the annoying Google ads.
An example usage for je
might be:
cmp eax, ebx
je RET_FAIL
jmp RET_SUCCESS
RET_FAIL:
push 1
pop eax
ret
RET_SUCCESS:
push 0
pop eax
ret
answered Oct 17, 2009 at 19:11
mrduclawmrduclaw
3,9654 gold badges36 silver badges37 bronze badges
2
Well, I finally found my answer. Basically you call je label_to_jump_to after a cmp call.
If cmp shows that the two values are equal, je will jump to the specified label. If not, it will keep execution flowing.
answered Oct 17, 2009 at 19:10
QAHQAH
4,20013 gold badges44 silver badges52 bronze badges
2