Файл: О.А.Калашников. Ассемблер Это Просто. Учимся программировать.pdf
Добавлен: 16.02.2019
Просмотров: 29212
Скачиваний: 1689
Глава 7. Операторы сравнения
67
Теперь мы знаем код клавиши <Y>! Естественно, можно сразу записать и
cmp
al,59h
. Программа будет работать правильно.
Таким образом, мы узнали, что в ассемблере можно записывать не только двоичные,
десятичные и шестнадцатеричные числа, но и просто символы (листинг 7.3).
Листинг 7.3. Пример загрузки символов в регистры
...
mov al,'2'
mov dh,'d'
...
В результате
al
будет содержать
32h
, а
dh
—
64h
. Все просто!
В строке (04) наша программа перейдет на метку
Yes_key
(05), если нажата кла-
виша <Y>. Оператор
jz
(от англ. jump if zero — переход, если флаг нуля установ-
лен) выполняет переход на указанную метку, если флаг нуля установлен.
Мы подошли вплотную к изучению регистра флагов. Полностью мы их в дан-
ной главе не будем рассматривать, а коснемся лишь того, что нужно для проверки
нажатой клавиши.
Флаг нуля устанавливается в единицу, если предыдущая команда сравнения бы-
ла верной (листинги 7.4 и 7.5).
Листинг 7.4. Установка флага нуля
...
mov ax,15
cmp ax,15
jz Our_lab
mov ah,3
Our_lab:
...
Во фрагменте кода из листинга 7.4 флаг нуля будет установлен, и процессор пе-
рейдет на указанную метку
Our_lab
. Команда
mov ah,3
не будет выполняться.
Листинг 7.5. Флаг нуля не установлен
...
mov ax,15
cmp ax,16
jz Our_lab
mov ah,3
Our_lab:
...
Часть II. Усложняем задачи
68
В участке кода из листинга 7.5 процессор не перейдет на метку
Our_lab
, т. к.
команда сравнения
cmp ax,16
не будет верна. Выполнится инструкция
mov ah,3
и,
естественно, все, что идет после данной инструкции.
Допустим, нам нужно подождать, пока пользователь нажмет какую-нибудь кла-
вишу. И если это <Ф> или <ф>, то перейти на указанную метку. В противном слу-
чае, запросить клавишу снова. Обратите внимание, что коды ПРОПИСНЫХ
и строчных букв различаются! В листинге 7.6 приведен пример.
Листинг 7.6. Проверка нажатия клавиши <Ф> или <ф>
...
Next_key:
mov ah,10h
int 16h
cmp al,'ф'
jz F_pressed
cmp al,'Ф'
jz F_pressed
jmp Next_key
F_pressed:
mov ah,9
mov dx,offset Mess
int 21h
int 20h
Mess db 'Вы нажали <Ф> или <ф>!!!$'
...
Стоит отдельно отметить, что команды
jz
и
je
(от англ. jump if equal — переход,
если равно) выполняют одну и ту же функцию. То есть корректной и идентичной
листингу 7.6 будет запись, приведенная в листинге 7.7.
Листинг 7.7. Использование оператора je вместо jz
...
int 16h
cmp al,'Ф'
je F_pressed
...
Команда
je
переведется программой-ассемблером в
jz
. Это легко проверить,
если после ассемблирования запустить программу под отладчиком. Разницы между
je
и
jz
нет никакой!
Глава 7. Операторы сравнения
69
7.3. Понятия условного
и безусловного переходов
Команда
jmp
(которую мы уже не раз рассматривали) называется командой без-
условного перехода. То есть при любом условии компьютер перейдет на указанную
метку. Для тех, кто знаком немного с Бейсиком: эта команда эквивалентна
goto
.
goto 20 — переход на строку 20
Команды вида
je
и
jz
являются командами условного перехода. То есть компь-
ютер перейдет на метку только, если какое-то условие выполняется или не выпол-
няется. В нашем случае — если нажата клавиша, которую мы проверяем:
cmp
al,'Ф'
. В Бейсике это выглядит примерно так:
if Key = "Ф" then goto 20
Иногда мы пишем, что компьютер сделает то-то или то-то. На самом деле, гра-
мотнее говорить, что процессор выполнит то или иное действие. Мы посылаем
команды не компьютеру (компьютер — это общее понятие), а процессору, который
и выполняет наши команды, причем команды ассемблера и только. Программа, на-
писанная на любом другом языке высокого уровня (например, Бейсике, Паскале,
Си, Ада и пр.), переводится в машинный код. Проблема в том, что ни один язык
высокого уровня не способен создать из команд своего языка оптимальный ма-
шинный код. Ассемблер — это создание машинного кода "вручную". А что может
быть лучше ручной работы?
7.4. Расширенные коды ASCII
Теперь рассмотрим таблицу некоторых кодов символов расширенного кода
ASCII.
Что такое расширенный код ASCII? Мы писали, что код клавиши, получаемый
функцией
10h
прерывания
16h
, возвращается в регистр
ax
. Но в приведенных ранее
примерах мы проверяли почему-то только содержимое регистра
al
:
cmp al,'Y'
Дело в том, что кроме символов (А...Я/A...Z), цифр (0,..., 9) и других символов
существуют еще другие клавиши, такие как, например, <F1>—<F12>. Мы не мо-
жем записать так, проверяя, нажата ли клавиша <F1>:
cmp al,'F1'
В процессе ассемблирования произойдет ошибка, потому что
'F1'
— 2 байта,
а регистр
al
может хранить только 1 байт. Для этого используются расширенные
коды ASCII. При этом, если мы на запрос нашей программы нажмем клавишу
<F1>, то в
al
помещается 0, а в
ah
— расширенный код.
В табл. 7.2 приведены расширенные ASCII-коды некоторых часто используемых
клавиш.
Часть II. Усложняем задачи
70
Таблица 7.2. Расширенные коды ASCII некоторых клавиш
Клавиши
Коды ASCII
<F1>, ..., <F10>
3Bh, ..., 44h
<Alt>+<F1>, ..., <Alt>+<F10>
68h, ..., 71h
<Shift>+<F1>, ..., <Shift>+<10>
54h, ..., 5Dh
<Ctrl>+<F1>, ..., <Ctrl>+<F10>
5Eh, ..., 67h
Из таблицы видно, что клавиша <F1> имеет код 3Bh, <F2> — 3Ch, <F3> — 3Dh
и т. д.
В листинге 7.8 приведена выдержка из программы, в которой мы проверим на-
жатие комбинации клавиш <Shift>+<F4> (в данном случае нужно нажать клавишу
<Shift> и, не отпуская ее, клавишу <F4>).
Листинг 7.8. Проверка расширенного кода ASCII
...
(01) No_ext:
(02) mov ah,10h
(03) int 16h
(04) cmp al,0
(05) jnz No_ext
(06) cmp ah,57h
(07) je Shift_f4
(08) jmp No_ext
(09) Shift_f4:
...
Мы уже выяснили, что при нажатии клавиши типа <F1>, <Alt>+<F1> и т. п. в
al
помещается 0, а в
ah
— расширенный код. В строках (04)—(07) мы это и проверя-
ем. В строке (05) переходим на метку
No_ext
, если пользователь нажал клавишу,
код которой не расширенный (например: <A>, <ф>, <Пробел>, <Enter> и т. п.). То
есть мы как бы просто проигнорируем нажатую клавишу и "попросим" пользовате-
ля нажать другую. В строке (06) проверяем, нажата ли именно комбинация клавиш
<Shift>+<F4>. Если же пользователь нажал <Shift>+<F4>, то, как не трудно дога-
даться, программа перейдет на метку
Shift_f4
— строка (09) (метку
Shift_f4
, ес-
тественно, можно было назвать по-другому). Если пользователь нажал какую-либо
иную клавишу, имеющую расширенный код, то программа опять-таки вернется на
метку
No_ext
(08).
Глава 7. Операторы сравнения
71
Итак, программа продолжит работу, только если пользователь нажмет комбина-
цию клавиш <Shift>+<F4>.
В табл. 7.3 приведены коды других часто используемых клавиш, но не расширен-
ные, т. е. эти коды будут загружаться функцией
10h
прерывания
16h
в регистр
al
.
Таблица 7.3. Коды часто используемых клавиш
Клавиша
Код
<Enter>
0Dh (13)
<ESC>
1Bh (27)
<
Пробел> (<Spacebar>)
20h (32)
<Tab>
09h (9)
П
Р И МЕ Ч А Н И Е
В скобках указаны десятичные числа.
Эти коды желательно запомнить. Полный перечень кодов ASCII находится
в приложении 3.
7.5. Программа для практики
В данном разделе мы рассмотрим программу (\007\prog07.asm), описание к ко-
торой будет приведено в главе 8. Ваша задача — постараться разобрать ее само-
стоятельно (листинг 7.9).
Листинг 7.9. Программа для практики
CSEG segment
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
org 100h
Begin:
call Wait_key
cmp al,27
je Quit_prog
cmp al,0
je Begin
call Out_char
jmp Begin
Quit_prog:
mov al,32