Файл: О.А.Калашников. Ассемблер Это Просто. Учимся программировать.pdf
Добавлен: 16.02.2019
Просмотров: 29211
Скачиваний: 1689
Часть II. Усложняем задачи
72
call Out_char
int 20h
; === Подпрограммы ===
; --- Wait_key ---
Wait_key proc
mov ah,10h
int 16h
ret
Wait_key endp
; --- Out_char ---
Out_char proc
push cx
push ax
push es
push ax
mov ax,0B800h
mov es,ax
mov di,0
mov cx,2000
pop ax
mov ah,31
Next_sym:
mov es:[di],ax
inc di
inc di
loop Next_sym
pop es
pop ax
pop cx
ret
Out_char endp
CSEG ends
end Begin
Пожалуйста, внимательно набирайте программу! Если что-то не работает, то
ищите опечатку в вашем наборе. Набранную ассемблерную программу (как и все
Глава 7. Операторы сравнения
73
файлы-приложения) можно найти на прилагаемом к книге компакт-диске или на
сайте http://www.Kalashnikoff.ru. А если возникнут вопросы, то вы в любое время
без тени сомнения можете задать их нашим экспертам на портале http://RFpro.ru.
Э
Т О И Н Т Е Р Е С Н О
Если посмотреть возможности языка ассемблера, то получается, что языки высокого
уровня могут делать практически то же самое и даже лучше.
Зачем нужен ассемблер? Что он может делать, что не сможет сделать любой другой
язык? Ведь неинтересно изучать то, что не понимаешь!
И в самом деле, уважаемые читатели! Чем же ассемблер лучше других языков, какие
у его достоинства и недостатки? Попробуем все их перечислить.
Достоинства:
программа, написанная на ассемблере, максимально быстро работает (в 50—
200
раз быстрее программы на Бейсике и в 3—20 раз быстрее программы на С++);
код программы максимально компактен;
позволяет делать то, что ни один язык высокого уровня не способен сделать.
Недостатки:
больше времени затрачивается на написание программы;
код (листинг) длиннее, чем в других языках;
в какой-то степени сложнее других языков.
Однако вы в дальнейшем поймете, что стоит один раз написать процедуры (напри-
мер, вывод окна заданных размеров на экран, получение строки символов и пр.), а за-
тем вызывать их из других программ. В итоге, времени у вас займет не настолько
больше, чем писать, например, на Паскале. Наибольший эффект достигается при
комбинировании двух языков: Паскаля и ассемблера или С и ассемблера. Это стано-
вится особенно актуально при программировании под Windows.
Кстати, о Windows. Программирование под Win32 на ассемблере мало чем отличает-
ся от программирования на языках высокого уровня. Если в DOS скорость работы за-
висит от использования языка и профессионализма программиста, то в Windows ско-
рость зависит в основном от операционной системы.
Многие нам возразят: зачем, мол, учитывать скорость, считать такты, оптимизировать
программы, уменьшать код, если и так большинство пользователей работает за со-
временными компьютерами, скорость работы которых очень и очень высока, и разни-
ца в несколько тысяч тактов на глаз не заметна?
Перечислим некоторые аспекты, когда требуется знание ассемблера.
Ассемблер часто используется для написания драйверов или ядра операционной
системы, где размер программы важен, а скорость выполнения отдельных участ-
ков кода очень критична, и программисты учитывают буквально каждый бит и каж-
дый такт.
Существуют задачи, реализация которых без применения ассемблера невозмож-
на, т. к. языки высокого уровня просто бесполезны и не отвечают необходимым
требованиям.
Ассемблер применяют и в случаях, когда нужно исследовать другие программы,
исходный код которых отсутствует. При этом, абсолютно не важно, на каком языке
была написана та или иная программа. Готовый код дизассемблируется и иссле-
дуется программистами.
Знание ассемблера также требуется, когда необходимо написать компактную про-
грамму и прошить ПЗУ. Это часто применяется в компаниях, которые занимаются
разработкой систем безопасности.
Именно в таких случаях требуются высококвалифицированные программисты на ас-
семблере.
Глава 8
Учимся работать с файлами
8.1. Программа из прошлой главы
В принципе, ничего сложно в программе из главы 7 не было. Единственное, на
чем был сделан акцент, — это на переводе шестнадцатеричных чисел в десятич-
ные. Задача-минимум — запомнить некоторые часто используемые шестнадцате-
ричные, десятичные числа и соответствующие им клавиши. Например:
20h — 32, клавиша <Пробел>;
100h — 256, круглое число;
1Bh — 27, клавиша <Esc>;
21h — 33, сервис MS-DOS
и т. п.
Теперь рассмотрим выдержки из программы с комментариями (листинг 8.1).
Листинг 8.1. Обзор программы из главы 7
...
(01) call Wait_key ;ждем нажатия клавиши...
(02) cmp al,27 ;это <Esc>?
;Если да — то на метку Quit_prog (quit — выход, prog (program) — программа)
(03) je Quit_prog
(04) cmp al,0 ;код клавиши расширенный? (<F1>-<F12> и т. п.)
(05) je Begin ;да — повторим запрос...
;Вызываем процедуру вывода нажатой клавиши на экран
(06) call Out_char
(07) jmp Begin ;ждем дальше...
;Метка, на которую придет программа в случае нажатия клавиши <Esc>
(08) Quit_prog:
(09) mov al,32 ;помещаем в al <пробел>
;Вызываем процедуру вывода символа в al (в данном случае — пробела).
;Здесь мы как бы "обманываем" процедуру Out_char, которая нужна для вывода
;нажатого символа на экран. Мы симулируем нажатие клавиши <Пробел>
Глава 8. Учимся работать с файлами
75
;и вызываем процедуру.
(10) call Out_char
(11) int 20h ;выходим в DOS...
(12) ...
(13) ; --- Out_char --- ;процедура (комментарий)
(14) Out_char proc ;начало процедуры
;Сохраним все регистры, которые будут изменены подпрограммой...
(15) push cx
(16) push ax
(17) push es ;сохраним сегментный регистр
(18) push ax ;сохраним ax, т. к. в нем код нажатой клавиши...
(19) mov ax,0B800h ;установим es на сегмент видеобуфера
(20) mov es,ax
(21) mov di,0 ;di — первый символ первой строки
;Выводим 2000 символов (80 символов в строке * 25 строк)
(22) mov cx,2000
(23) pop ax ;восстановим код клавиши (см. строку 18)...
(24) mov ah,31 ;цвет символа
;Метка для цикла, который выполнится 2000 раз (количество повторов
;задается в строке 22)
(25) Next_sym:
;Заносим код клавиши и ее цвет (цвет всегда 31)
(26) mov es:[di],ax
;Увеличиваем указатель на 2 (первый байт — символ, второй байт — цвет)
(27) inc di
(28) inc di
(29) loop Next_sym ;обработка следующего символа
;Восстановим сохраненные регистры и выровняем стек
(30) pop es
(31) pop ax
(32) pop cx
(33) ret ;вернемся из подпрограммы
(34) Out_char endp
...
Часть II. Усложняем задачи
76
В строке (12) для экономии места опущена процедура ожидания нажатия кла-
виши. В целом же, программа делает следующее:
ждет от пользователя нажатия любой клавиши;
если это расширенный код ASCII (<F1>—<F12>, кнопки со стрелками), то игно-
рирует ее;
если это не расширенный ASCII (<A>—<Z>, <0>—<9> и т. п.) — заполняет эк-
ран данным символом;
если нажимаем клавишу <Esc> (
27
или
1Bh
), то заполняет экран пробелами
(
mov al,32
) и выходит.
8.2. Основы работы с файлами
В настоящем разделе рассмотрим функции MS-DOS для работы с файлами
и общий принцип.
Для того чтобы прочитать содержимое файла, необходимо вначале открыть его.
Это позволяет сделать функция
3Dh
прерывания
21h
(табл. 8.1).
Таблица 8.1. Функция
3Dh
прерывания
21h
— открытие файла
Вход
Выход
ah = 3Dh
al
= тип открытия (00 — только чтение, 01 — только
запись, 02 — и чтение, и запись)
ds:dx
= адрес ASCII-строки с именем файла
ax
= номер файла
jc
— ошибка
Итак, на входе
al
должен содержать тип открытия, т. е. указание на действие,
для которого открывается файл:
только чтение;
только запись;
чтение и запись.
Естественно, при открытии файла для чтения и записи (
al=02
) мы не обязаны
прочитать его, а затем что-то записать. Можно только прочитать файл и/или запи-
сать что-то в него, а можно вообще ничего не делать. Однако следует иметь в виду,
что если мы попытаемся открыть файл с атрибутом "только чтение" ("read-only")
для записи (
al=2
) или для чтения/записи (
al=02
), то функция вернет ошибку. Код
из листинга 8.2 пробует открыть файл command.com из текущего каталога для чте-
ния/записи.
Листинг 8.2. Открытие файла для чтения/записи
...
mov ax,3D02h
mov dx,offset File_name