Файл: О.А.Калашников. Ассемблер Это Просто. Учимся программировать.pdf

ВУЗ: Не указан

Категория: Книга

Дисциплина: Программирование

Добавлен: 16.02.2019

Просмотров: 29212

Скачиваний: 1689

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Глава 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: 
... 


background image

 

Часть 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

 нет никакой! 


background image

Глава 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-коды некоторых часто используемых 

клавиш. 


background image

 

Часть 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). 


background image

Глава 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