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

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

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

background image

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

background image

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

  можно  было  бы  использовать  любое 

background image

Глава 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        ;то же самое, только другие числа 

background image

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

 адрес этого сообщения. 

Источник: https://files.student-it.ru/previewfile/2839