Файл: О.А.Калашников. Ассемблер Это Просто. Учимся программировать.pdf
Добавлен: 16.02.2019
Просмотров: 29194
Скачиваний: 1689
Часть I. Знакомьтесь: ассемблер
10
Таблица 1.1 (окончание)
Десятичное
число
Шестнадцатеричное
число
Десятичное
число
Шестнадцатеричное
число
9
9
159
9F
10
A
160
A0
11
B
161
A1
12
C
162
A2
13
D
...
...
14
E
254
FE
15
F
255
FF
16
10
256
100
17
11
257
101
...
...
...
...
Таким образом, если мы к какому-нибудь числу в шестнадцатеричной системе
добавим справа ноль, то это число увеличится в 16 раз (пример 1.1).
Пример 1.1
1 х 16 = 10
10 х 16 = 100
100 х 16 = 1000
и т. д.
Вы смогли отличить в примере 1.1 шестнадцатеричные числа от десятичных?
А из этого ряда: 10, 12, 45, 64, 12, 8, 19? Это могут быть как шестнадцатеричные
числа, так и десятичные. Для того чтобы не было путаницы, а компьютер и про-
граммист смогли бы однозначно отличить одни числа от других, в ассемблере при-
нято после шестнадцатеричного числа ставить символ h или H (от англ.
hexadecimal — шестнадцатеричное), который для краткости часто называют просто
hex. После десятичного числа, как правило, ничего не ставят. Так как числа от 0 до
9 в обеих системах имеют одинаковые значения, то числа, записанные как 5 и
5h, — одно и то же. Таким образом, корректная запись чисел из примера 1 будет
следующей (примеры 1.2 и 1.3).
Пример 1.2. Корректная форма записи чисел
1 х 16 = 10h
10h x 16 = 100h
100h x 16 = 1000h
Глава 1. Первая программа
11
Пример 1.3. Другой вариант записи чисел
1h x 10h = 10h
10h x 10h = 100h
100h x 10h = 1000h
Для чего нужна шестнадцатеричная система и в каких случаях она применяет-
ся — мы рассмотрим в следующих главах. А в данный момент для нашего примера
программы, который будет рассмотрен далее, нам необходимо знать о существова-
нии шестнадцатеричных чисел.
Итак, настала пора подвести промежуточный итог. Шестнадцатеричная система
счисления состоит из 10 цифр (от 0 до 9) и 6 букв латинского алфавита (A, B, C, D,
E, F). Если к какому-нибудь числу в шестнадцатеричной системе добавить справа
ноль, то это число увеличится в 16 раз. Очень важно уяснить принцип шестнадца-
теричной системы счисления, т. к. мы будем постоянно использовать ее при напи-
сании наших программ на ассемблере.
Теперь немного о том, как будут строиться примеры на ассемблере в данной
книге. Не совсем удобно приводить их сплошным текстом, поэтому сперва будет
идти сам код программы с пронумерованными строками, а сразу же после него —
объяснения и примечания. Примерно так, как показано в листинге 1.1.
Листинг 1.1. Пример записи ассемблерных инструкций, применяемой в книге
...
(01) mov ah,9
(02) mov al,8
...
(15) mov dl,5Ah
...
Обратите внимание, что номера строк ставятся только в книге, и при наборе
программ в текстовом редакторе эти номера ставить НЕ нужно! Номера строк ста-
вятся для того, чтобы удобно было давать объяснения к каждой строке: в строке
(01) мы делаем то-то, а в строке (15) — то-то.
Несмотря на то, что на компакт-диске, прилагаемом к книге, имеются набран-
ные и готовые для ассемблирования программы, мы рекомендуем все-таки первое
время набирать их самостоятельно. Это ускорит запоминание операторов, а также
облегчит привыкание к самому языку.
И еще момент. Строчные и ПРОПИСНЫЕ символы программой-ассемблером не
различаются. Записи вида:
mov ah,9
и
MOV AH,9
Часть I. Знакомьтесь: ассемблер
12
воспринимаются одинаково. Можно, конечно, заставить ассемблер различать ре-
гистр, но мы пока этого делать не будем. Для удобства чтения программы лучше
всего операторы вводить строчными буквами, а названия подпрограмм и меток на-
чинать с прописной.
1.2. Наша первая программа
Итак, переходим к нашей первой программе (\001\prog01.asm) (листинг 1.2).
Листинг 1.2. Наша первая программа на ассемблере
(01) CSEG segment
(02) org 100h
(03)
(04) Begin:
(05)
(06) mov ah,9
(07) mov dx,offset Message
(08) int 21h
(09)
(10) int 20h
(11)
(12) Message db 'Hello, world!$'
(13) CSEG ends
(14) end Begin
Еще раз обратим внимание: когда вы будете перепечатывать примеры про-
грамм, то номера строк ставить не нужно!
В скобках указывается имя файла из архива файлов-приложений (в данном слу-
чае — \001\prog01.asm, где 001 — каталог, prog01.asm — имя ассемблерного файла
в DOS-формате).
Прежде чем пытаться ассемблировать, прочтите данную главу до конца!
Для того чтобы объяснить все операторы из листинга 1.2, нам потребуется не-
сколько глав. Поэтому описание некоторых команд мы на данном этапе опустим.
Просто считайте, что так должно быть. В ближайшее время мы рассмотрим эти
операторы подробно. Итак, строки с номерами (01), (02) и (13) вы игнорируете.
Строки (03), (05), (09) и (11) остаются пустыми. Это делается для наглядности
и удобства программиста при просмотре и анализе кода. Программа-ассемблер
пустые строки опускает.
Теперь перейдем к рассмотрению остальных операторов. Со строки (04) начи-
нается код программы. Это метка, указывающая ассемблеру на начало кода.
В строке (14) стоят операторы
end Begin
(
Begin
— начало;
end
— конец). Это ко-
нец программы. Вообще вместо слова
Begin
можно было бы использовать любое
Глава 1. Первая программа
13
другое. Например,
Start
. В таком случае, нам пришлось бы и завершать программу
оператором
End Start
(14).
Строки (06)—(08) выводят на экран сообщение "Hello, world!". Здесь придется
вкратце рассказать о регистрах процессора (более подробно эту тему мы рассмот-
рим в последующих главах).
Регистр процессора — это специально отведенная память для хранения какого-
нибудь числа. Например, если мы хотим сложить два числа, то в математике запи-
шем так:
A = 5
B = 8
C = A + B
A, B и C — это своего рода регистры (если говорить о компьютере), в которых мо-
гут храниться некоторые данные. А = 5 следует читать как: "присваиваем А число 5".
Для присвоения регистру какого-нибудь значения в ассемблере существует опе-
ратор
mov
(от англ. move — в данном случае "загрузить"). Строку (06) следует чи-
тать так: "загружаем в регистр
ah
число 9" (проще говоря, присваиваем
ah
чис-
ло 9). Далее рассмотрим, зачем это необходимо. В строке (07) загружаем в регистр
dx
адрес сообщения для вывода (в данном примере это будет строка
"Hello,
world!$"
). Затем, в строке (08) вызываем прерывание MS-DOS, которое и выведет
нашу строку на экран. Прерывания будут подробно рассматриваться в последую-
щих главах, мы же пока коснемся только самых элементарных вещей.
1.3. Введение в прерывания
Прерывание MS-DOS — это своего рода подпрограмма (часть MS-DOS), которая
находится постоянно в памяти и может вызываться в любое время из любой про-
граммы. Рассмотрим вышесказанное на примере (листинг 1.3).
Сразу стоит отметить, что в ассемблере после точки с запятой располагаются
комментарии. Комментарии будут опускаться MASM/TASM при ассемблирова-
нии. Примеры комментариев:
;это комментарий
mov ah,9 ;это комментарий
В комментарии программист вставляет замечания по программе, которые помо-
гают сориентироваться в коде.
Листинг 1.3. Программа (алгоритм) сложения двух чисел
НачалоПрограммы
A=5 ;в переменную A заносим значение 5
B=8 ;в переменную B значение 8
ВызовПодпрограммы Addition
;теперь С равно 13
A=10 ;то же самое, только другие числа
Часть I. Знакомьтесь: ассемблер
14
B=25
ВызовПодпрограммы Addition
;теперь С равно 35
КонецПрограммы
;выходим из программы
...
Подпрограмма Addition
C = A + B
ВозвратИзПодпрограммы
;возвращаемся в то место, откуда вызывали
КонецПодпрограммы
В данном примере мы дважды вызвали подпрограмму (процедуру)
Addition
,
которая произвела сложение двух чисел, переданных ей в переменных
A
и
B
. Ре-
зультат математического действия сохраняется в переменной
С
. Когда вызывается
подпрограмма, компьютер запоминает, с какого места она была вызвана, и после
того, как процедура отработала, возвращается в то место, откуда она вызывалась.
Таким образом, можно вызывать подпрограммы неопределенное количество раз
с любого участка основной программы.
При выполнении строки (08) (см. листинг 1.2) мы вызываем подпрограмму
(в данном случае это называется прерыванием), которая выводит на экран строку.
Для этого мы, собственно, и помещаем нужные значения в регистры, т. е. готовим
для прерывания необходимые параметры. Всю работу (вывод строки, перемещение
курсора) берет на себя эта процедура. Строку (08) следует читать так: "вызываем
двадцать первое прерывание" (
int
от англ. interrupt — прерывание). Обратите
внимание, что после числа 21 стоит буква h. Это, как мы уже знаем, шестнадцате-
ричное число (33 в десятичной системе). Конечно, нам ничего не мешает заменить
строку
int 21h
строкой
int 33
. Программа будет работать корректно. Но в ас-
семблере принято указывать номера прерываний в шестнадцатеричной системе, да
и все отладчики работают с этой системой.
В строке (10) мы, как вы уже догадались, вызываем прерывание
20h
. Для его
вызова не нужно указывать какие-либо значения в регистрах. Оно выполняет толь-
ко одну задачу — выход из программы (выход в DOS). В результате выполнения
прерывания
20h
программа вернется туда, откуда ее запускали (загружали, вызыва-
ли). Например, в Norton Commander или DOS Navigator. Это что-то вроде оператора
exit
в некоторых языках высокого уровня.
Строка (12) содержит сообщение для вывода. Первое слово (
message
— сооб-
щение) — название этого сообщения. Оно может быть любым (например,
mess
или
string
и пр.). Обратите внимание на строку (07), в которой мы загружаем в регистр
dx
адрес этого сообщения.