Команды условного перехода и флаги
Мнемоническое обозначение некоторых команд условного перехода отражает название флага, с которым они работают, и имеет следующую структуру: первым идет символ «j» (jump ~ переход), вторым — либо обозначение флага, либо символ отрицания «n», после которого стоит название флага. Такая структура команды отражает ее назначение. Если символа «п» нет, то проверяется состояние флага и, если он равен 1, производится переход на метку перехода. Если символ «n» присутствует, то проверяется состояние флага на равенство 0 и в случае успеха производится переход на метку перехода. Мнемокоды команд, названия флагов и условия переходов приведены в табл. 10.3. Эти команды можно использовать после любых команд, изменяющих указанные флаги.
Таблица 10.3. Команды условного перехода и флаги
Название флага |
Номер бита в регистре eflags/flags |
Команда условного перехода |
Значение флага для осуществления перехода |
Переноса CF |
1 |
JC |
CF=1 |
Четности PF |
2 |
JP |
PF=1 |
Нуля ZF |
6 |
JZ |
ZF=1 |
Знака SF |
7 |
JS |
SF=1 |
Переполнения OF |
11 |
JO |
OF-1 |
Переноса CF |
1 |
JNC |
CF = 0 |
Четности PF |
2 |
JNP |
PF = 0 |
Нуля ZF |
6 |
JNZ |
ZF = 0 |
Знака SF |
7 |
jns |
sf=0 |
Переполнения OF |
11 |
JNO |
OF = 0 |
Если внимательно посмотреть на табл. 10.2 и 10.3, видно, что многие команды условного перехода в них эквивалентны, так как в них анализируются одинаковые флаги.
В листинге 10.1 приведен пример программы, производящей в строке символов длиной nбайт замену строчных букв английского алфавита прописными. Для осмысленного рассмотрения этого примера вспомним ASCII-коды, соответствующие этим буквам (см. главу 6). Строчные и прописные буквы в таблице ASCII упорядочены по алфавиту. Строчным буквам соответствует диапазон кодов 61h-7ah, прописным — 41h-5ah. Для того чтобы понять идею, лежащую в основе алгоритма преобразования, достаточно сравнить представления соответствующих прописных и строчных букв в двоичном виде:
a-01100001...z-0111 1010
А - 0100 0001...Z - 0101 1010
Как видно из приведенного двоичного представления, для выполнения преобразования между строчными и прописными буквами достаточно всего лишь инвертировать 5-й бит.
Листинг 10.1. Смена регистра символов
<1> ;prg_l0_1 .asm
<2> model small
<3>.stack 100h
<4>.data
<5> nequ10 ; количество символов в stroka
<6> strokadb "acvfgrndup"
<7> .code
<8> start:
<9> mov ax,@data
<10> mov ds.ax
<11> xor ax,ax
<12> mov cx,n
<13> lea bx,stroke ;адрес stroka в bx
<14>ml:moval,[bx] ;очередной символ из stroka в al
<15>cmpal,61h;убедиться, что код символа не меньше 61h
<16>jbnext;если меньше, то не обрабатывать
<17>;и перейти к следующему символу
<18>cmpal,7ah;убедиться, что код символа не больше 7ah
<19>janext;если больше, то не обрабатывать
<20>;и перейти к следующему символу
<21> and al.ll0lllllb;инвертировать 5-й бит
<22> mov[bx],al;символ - на его место в stroka
<23> next:
<24> incbx;адресовать следующий символ
<25> decex;уменьшить значение счетчика в сх
<26> jnzml;если сх не 0, то переход на ml
<27> exit:
<28> mov ax,4c00h
<29> int21h;возврат управления операционной системе
<30> end start
Обратите внимание на строку 25 листинга. Команда DEC уменьшает значение регистра СХ на 1. Когда это значение станет равным 0, процессор по результату операции декремента установит флаг ZF. Команда в строке 26 анализирует состояние этого флага и, пока он не равен 1 (см. табл. 10.3), передает управление на метку ml. Заметьте, что на место этой команды можно было бы поставить команду JNE (см. табл. 10.2). Но для анализа регистра СХ в системе команд процессора есть специальная команда, которую мы сейчас и рассмотрим.