ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ АССЕМБЛЕРА |
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 | [Оставить отзыв в гостевой] |