ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ АССЕМБЛЕРА
ПОД MS-DOS

1998 год
Новиков Максим Глебович.

Глава 8. Разбор и оптимизация записи исходного текста нашей программы

Давай разберем написанную нами ранее программу, и посмотрим, какая команда в ней что обозначает. Для удобства написания программы мы использовали язык ассемблер, который позволяет писать программу не двоичными, и даже не шестнадцатеричными кодами, а специальными сокращенными английскими словами, состоящими в основном из трех букв (представляю, что это были бы за слова, если бы ассемблер придумал русский программист).

Эти сокращенные английские слова называются мнемоникой, а полученный текст — мнемокодом. Лично мне очень нравится звучание этого слова :-)

После сохранения мнемокода в текстовом файле, называемом исходником (исходным текстом программы), он переводится в двоичный код программой ассемблера (помнишь, мы запускали tasm и tlink?).

Итак, вот наша программа с подробными комментариями. Комментарии я буду предворять знаком «;». Тогда их можно будет оставить в исходнике. Они не будут восприниматься ассемблером, и в состав программы не войдут. Они нужны лишь для нашего удобства при написании и дальнейшей модернизации нашей программы.

;Сначала идет общая для большинства программ шапка.

.model tiny   ;Это приказ ассемблеру создать программу самой
              ;компактной модели. Но в этом случае ее размер 
              ;не должен превышать 65536 байт. 

.code org 256 ;Начать программу с адреса 256, что соответствует 
              ;стандарту компактной модели.
              ;Затем начинаются собственно команды.

b:            ;Метка, заставляющая ассемблер запомнить адрес 
              ;следующей команды.

;Здесь начинается основной код программы.

mov dx,264    ;Поместить в регистр DX число 264. Это адрес памяти, 
              ;где хранится код первой буквы слова «hello». 

mov ah,9      ;AH — это левая половинка регистра AX. Занесем туда 
              ;номер подпрограммы (функции) указанного ниже 
              ;прерывания. 

int 33        ;Вызовем прерывание 33, соответствующее прерыванию 
              ;операционной системы, функция 9 которого печатает 
              ;на экране строку текста. 

ret           ;Вернемся из программы в операционную систему. 

А дальше расположим данные. 

db 'hello$'   ;Код каждой буквы занимает 1 байт, поэтому 
              ;символами «db» укажем, что данные (d) имеют 
              ;размерность байта (b).Если бы нам надо было
              ;указать число, занимающее 2 байта,мы бы написали 
              ;«dw». «w» означает «слово» (word), то есть 2 
              ;байта. Далее в апострофах или кавычках следует 
              ;текст для распечатки. Ассемблер переведет его в 
              ;коды. Последний символ «$» имеет код 36, который 
              ;используется,как код окончания строки, выводимой 
              ;на печать. 

end b         ;Указание ассемблеру, что текст программы, 
              ;начавшийся с метки «b», закончен. 

Вышеописанная программа успешно выполняет свою функцию, но записана не совсем удобным способом. Так, мы не можем точно знать адрес, где начинается слово «hello». В нашем случае я его просто вычислил вручную, зная размер каждой команды. Но как быть, если программа очень большая? Ручной подсчет здесь тем более не имеет смысла. На помощь приходят метки.

Метка — это любое слово, состоящее из латинских букв и цифр, отмечающее определенное место в программе. По метке ассемблер автоматически вычисляет адрес. Как же это записать? Очень просто — вместо строки

db 'hello$' ;Данные, каждый элемент которых занимает 1 байт. 

напишем:

fraza:      ;Метка, заставляющая ассемблер запомнить адрес следующей команды.
db 'hello$' ;Данные, каждый элемент которых занимает 1 байт. 

а вместо

mov dx,264  ;Поместить в регистр DX число 264.
напишем: 
          
mov dx, offset fraza ;Поместить в регистр DX адрес памяти,
                     ;соответствующий метке «fraza». Этот адрес в нашем
                     ;случае равен числу 264
Если метка обозначает не команду (как метка «b» в начале программы), а данные, то используется сокращенный вариант обозначения метки, когда она пишется без двоеточия в одной строке с данными:
fraza db 'hello$'    ;Данные, каждый элемент которых занимает 1 байт,
                     ;помеченные меткой. 

Если метка обозначает не данные, а команду (как в случае с меткой «b»), двоеточие обязательно, но ее тоже можно писать в одной строке с командой:

b: mov dx,264        ;Поместить в регистр DX число 264,и отметить адрес этой
                     ;команды меткой.

Какие еще исправления можно сделать в нашей программе? Давай все числа запишем в шестнадцатеричном виде. В итоге у нас получится следующий текст:

;Шапка программы, осуществляющая настройку ассемблера

.model tiny             ;Зададим модель памяти. 
.code org 100h          ;Начать программу с адреса 100h.

;Затем начинаются собственно команды. 

b:  mov dx,offset fraza ;Адрес слова «hello» в регистр DX. 
    mov ah,09h          ;Номер фунции. 
    int 21h             ;Вызов прерывания 21h, печатающее
                        ;строку из адреса,указанного в DX
    ret                 ;Вернемся из программы в операционную
                        ;систему. 

;А дальше расположим данные. 

fraza db 'hello$'       ;Данные для печати 

end b                   ;Конец программы, начавшейся с адреса по метке «b». 

Как ты видишь, исходный текст стал более компактным, и не только за счёт сокращения комментариев. Сделай все описанные исправления в своем исходнике и откомпилируй его. В итоге ты получишь программу, ничем не отличающуюся от полученной тобой ранее, зато запись исходника стала компактней и намного удобней.

Кстати, строку

fraza db 'hello$' 

можно записать не буквами, а их кодами:

fraza db 69h, 65h, 6Ch, 6Ch, 6Fh, 24h

В любом случае в памяти они запомнятся одинаково, а именно в виде кодов, но такая запись менее наглядна и неудобна. Её применяют только в том случае, если данные представляют собой не коды букв, а отвлеченные значения, к кодам букв не относящиеся, хотя может быть и выражающиеся теми же числами.

[Вернуться в начало]
Главы 5–7
Главы 1–2 [Оставить отзыв в гостевой]
Hosted by uCoz