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

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

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

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

Добавлен: 16.02.2019

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

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

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

 

Часть II. Усложняем задачи 

62 

Этот  оператор  абсолютно  ничего  не  делает,  не  меняет  содержимое  регистров  

и флаги, но занимает 1 байт. Его обычно используют для резервирования места ли-
бо для того, чтобы "забить" ненужный код, когда исходник на ассемблере отсутст-
вует. Например, в случае, когда программа перед стартом проверяет версию опера-
ционной  системы,  а  версия,  которая  установлена  на  вашем  компьютере,  не 
соответствует  требуемой  программой.  Для  этого  данным  оператором  "забивают" 
участок кода, который проверяет версию ОС. Все это позволяет сделать редактор 
Hacker's View, который можно загрузить с сайта: http://www.Kalashnikoff.ru

Запомните  машинный  код  данной  команды: 

90h

.  Если  вы  в  любом  текстовом 

редакторе, который позволяет редактировать файлы в шестнадцатеричном формате 
(Volcov Commander, Hacker's View), вручную введете приведенные ниже строки, то 
получится коротенькая программа, которая абсолютно ничего не делает: 

90h 
90h 
0CDh 
20h 

6.2.2. Хитрая программа 

Рассмотрим одну очень интересную и хитрую программу (листинг 6.5). Ни на од-

ном другом языке программирования нельзя создать подобную (\006\prog06.asm). 

Листинг 6.5. Программа для практики 

(01) CSEG segment 
(02) assume cs:CSEG, es:CSEG, ds:CSEG, ss:CSEG 
(03) org 100h 
 
(04) Begin: 
(05)        mov sp,offset Lab_1 

(06)        mov ax,9090h 
(07)        push ax 
(08)        int 20h 
 
(09) Lab_1: 
(10)        mov ah,9 
(11)        mov dx,offset Mess 
(12)        int 21h 
 
(13)        int 20h 
 
(14) Mess db 'А все-таки она выводится! $' 
 
(15) CSEG ends 
(16) end Begin 


background image

Глава 6. Работа со стеком 

63 

То, что вы видите — "обман зрения". На первый взгляд, программа что-то дела-

ет  с  регистром 

sp

,  а  затем  завершает  работу.  Строки  (09)—(12)  вообще  не  будут 

работать. Но это глубокое заблуждение! Попробуйте запустить ее под отладчиком. 
Вы увидите, что CodeView, TurboDebuger, AFD будут выдавать какой-то "мусор": 
непонятные операторы, сообщения типа "программа завершилась", хотя до коман-
ды 

int 20h

 дело не дошло (рис. 6.7). Но если запустить ее просто из DOS, то стро-

ка появится на экране, т. е. программа будет работать корректно, при этом выводя 
строку на экран (рис. 6.8)! Данный пример — типичный случай "заламывания рук" 
многим отладчикам. И вы уже можете это делать! 

Почему так происходит? Ответ один: указанные выше отладчики используют стек 

пользовательской программы (т. е. той программы, которая работает под отладчиком). 

Ваша задача — разобрать "по полочкам" программу. 

 

Что происходит? 

 

Почему строка выводится? 

 

Почему отладчик работает неверно? 
Вопросов море. И вам необходимо дать ответ на них. Разобравшись с програм-

мой  самостоятельно,  вы  почувствуете  силу  и  неограниченные  возможности  ас-
семблера. Не бойтесь экспериментировать! Компьютер будет часто зависать, но это 
не главное! Ваши мучения приведут вас к пониманию работы процессора! 

 

Рис. 6.7. Некорректная работа отладчика с нашей программой 

 

Рис. 6.8. Корректная работа нашей программы без отладчика 


background image

 

 

 

Глава 7 

 

Операторы сравнения 

 

7.1. Разбор программы из главы 6 

В  начале  данной  главы  рассмотрим  прошлую  программу.  Итак,  в  листинге 7.1 

показано решение. 

Листинг 7.1. Программа из главы 6 

... 

(01)    mov sp,offset Lab_1 
(02)    mov ax,9090h 

(03)    push ax 
(04)    int 20h 
 
(05) Lab_1: 
(06)    mov ah,9 
(07)    mov dx,offset Mess 
(08)    int 21h 
(09)    int 20h 
... 

Что же все-таки происходит? 
Как мы узнали из главы 6, команда 

nop

 имеет машинный код 

90h

. Посмотрите на 

строку  (02).  В  ней  мы  загружаем  в  регистр 

ax

  два  числа 

90h

  (или  два  оператора 

nop

). В 

sp

 заносим адрес метки 

Lab_1

 (01). Теперь  стек находится внутри нашей 

программы,  а,  точнее,  вершина  стека  на  метке 

Lab_1

.  Стоит  отметить,  что  сама 

метка памяти не занимает! Она нужна только для MASM/TASM, которые, дойдя до 
строки (05), запомнят адрес (смещение) метки в программе (что равно 

109h

). 

После выполнения строки (01) посмотрите в отладчике, какое число находится в 

sp

а также на код, который расположен по этому адресу. Вы увидите, что по адресу 

109h

 

находится команда 

mov ah,09

, т. е. физически метки 

Lab_1

 в памяти не существует. 

Теперь внимание! В строке (03) мы "толкаем" в стек два числа 

90h

, т. е. две ко-

манды 

nop

. Что происходит дальше? Стек, как вы уже знаете, "растет" снизу вверх. 


background image

Глава 7. Операторы сравнения 

65 

После помещения в стек числа 

sp

 не увеличивается, а уменьшается, что отображе-

но стрелкой на рис. 7.1. Команда 

int 20h

 занимает 2 байта. Это можно наблюдать 

в отладчике или в Hacker's View. Машинный код 

int 20h

 равен 

0CDh, 20h

. Теперь 

вы знаете, как "вручную" набрать простейшую COM-программу в редакторе. Если 
есть  редактор,  позволяющий  смотреть  шестнадцатеричные  числа  (например, 
Volcov Commander), то введите в создаваемом файле 

CD

 и 

20

. Сохраните файл как 

COM (например, prog.com). Его размер должен быть 2 байта. Можете смело запус-
кать получившийся COM-файл. 

 

Рис. 7.1. Программа в отладчике AFD Pro 

Итак, 

int  20h

 занимает 2 байта. Командой 

push ax

 (03) мы заносим в стек два 

числа 

90h

, которые процессор воспримет как два оператора 

nop

.  Так как смещение 

в регистре 

sp

 указывает на 

int 20h

, то эта команда будет затерта двумя оператора-

ми 

nop

. Все! Вместо 

int 20h

 (завершение работы программы) процессор выполнит 

два оператора 

nop

, которые ничего не делают! После этого выведет строку на эк-

ран. На рис. 7.1 показан результат работы этой программы в отладчике. 

Обратите внимание, как легко можно менять код собственной программы в ас-

семблере буквально "на лету". 

Эта простая программа наглядно демонстрирует работу стека. 
Теперь рассмотрим, почему отладчики CodeView, AFD, Turbo Debugger работа-

ют  некорректно.  Внимательно  прочтите  следующую  фразу:  вышеперечисленные 
отладчики используют стек нашей программы. Говоря простым языком, отладчик, 
загрузив к себе в память нашу программу, использует тот же стек (те же регистры 

ss:sp

), что и наша программа. Отладчику ведь тоже надо хранить где-то свои дан-

ные.  Например,  после  выполнения  одной  команды  нашей  программы,  запомнить 
адрес следующей. Одно дело на экране, но другое — в стеке отладчика, который по 
сути  является  нашим!  Поэтому, переместив стек в область кода написанной нами 


background image

 

Часть II. Усложняем задачи 

66 

программы, мы тем самым переносим и стек отладчика, который, в свою очередь, 
сохраняет  в  нем  свои  данные.  Но  мы  знаем,  что  заносить  в  стек  можно  не  более 
двух байтов, иначе стек будет переполнен, т. к. мы очень уж мало места отвели под 
стек. Проблема отладчика в том, что он об этом "не знает", да и заносит в стек до-
вольно много информации, которая попросту затирает нашу программу. 

7.2. Оператор сравнения 

В предыдущих главах мы рассматривали функцию 

10h

 прерывания 

16h

, которая 

ждет  от  пользователя  нажатия  клавиши.  Теперь  настало  время  научиться  прове-
рять, какую же именно клавишу нажал пользователь. 

Вышеуказанная функция возвращает код нажатой клавиши в регистр 

ax

. Как же 

нам ее проверить? Для этого рассмотрим новый оператор сравнения 

cmp

 (табл. 7.1  

и листинг 7.2). 

Таблица 7.1. Оператор сравнения 

cmp

 

Команда 

Перевод 

Назначение 

Процессор 

cmp приемникисточник 

Compare 

— сравнить 

Сравнение 

8086 

 

Листинг 7.2. Пример использования оператора cmp 

... 
(01)    mov ah,10h 
(02)    int 16h 
(03)    cmp al,'Y' 
(04)    jz Yes_key 
... 
(05) Yes_key: 
... 

На строке (02) компьютер остановится и будет ждать до тех пор, пока пользова-

тель не нажмет какую-нибудь клавишу. После этого прерывание 

10h

 поместит в 

ax

 

код клавиши, и выполнение программы продолжится. В строке (03) мы проверяем, 
нажата ли клавиша <Y>. Обратите внимание на запись: 

cmp al,'Y' 

Нам  не  обязательно  знать  ASCII-код  клавиши.  Вместо  этого  в  одинарных  ка-

вычках  просто  указываем  саму  клавишу.  При  ассемблировании  программы 
MASM/TASM  автоматически  заменит  ее  соответствующим кодом. Если вы запус-
тите программу под отладчиком, то увидите, что код будет не 

cmp al,'Y' 

а 

cmp al,59h