В.Н. Пильщиков - Программирование на языке ассемблера IBM PC (1110551), страница 2
Текст из файла (страница 2)
1 ссьшка вперед л пв г чя х рв г +~ ива а-) 2.3. Директивы определении данных Ляя описания переменных, с которыми работает прогрэыиа, в ЯА используются директивы определения данных. Одна из иих предназначена для описания даииых разыероы в баГп, вторая - для описания данных размером в слово, атрею - для описаиия данных размером в двойное слово. В остачьиоц этя директивы практически це отличаются друг от друга. 2З.1. Директива РВ По директиве РВ (бейле Ъуге, опрелелить баГгг) определяются данине разиероы в байт. Ее синтаксис (без учета возможного коцыеитария в конце) таков: Чтобы различать эти случаи, вводят термины "ссылка назад" и "ссылка вперед".
Ссылка назад (сы. слева) - это ссылка иа иьш, которое по тексту програиыы описано раньше, а ссылка вперед (си. справа) - это ссылка иа юш, которое будет описано позже. При траисляции ассеыблер просыатривает текст программы иа ЯА сверху вниз. Коша оц встречает ссылку на шш, которое уже было описано, то ои, имея к этому ьюыецту всю информацию об иыеии, ыожет правильно отграислировать данную ссылку. Но если еыу встретилась ссылка вперед, т. е.
иия, которое еще ие описано и о котором оц пока ничего ие знает, то ои ие всегда может правильно оттранслировать эту ссылку и потому Здесь нередко возникают проблеыы. В связи с этим, хотя в целом ЯА и допускает ссылки вперед, в некоторых случаях такие ссылки запрещаются (эти случаи будут оговаривкпюя явно), поэтому лучше всего стараться ие использовать ссылки вперед. 2В Программирование не языке'ассемблере )ВМ РС Значениеь~ этого оператора является размер (в байтах) ячейки, выделенной под переменную с указанным именем. Если переыенная описана по директиве ГУВ, т.
е. как байтовая переменная, то лля ее имени значение РГого оператора равно 1. Отыетим, что в ЯА есть стандартная константа с именем ВУТЕ и значением 1, поэтоыу ыожно записать так: ЕРРе х = Втяе = 1 Операнд - константное выражение ео значением от -128 до 255 Мы рассмотрели, как можно описать переменную, которой не присваивается никжого начального значения. Но ЯА позволяет описывать и переменные с начачьныьги значениями. Для этого в качестве операнда директивы ПВ указывается выражение, которое ассемблер вычислит и значение которого запишет в ячейку, отведенную под переменную.
Это и есть начачьное значение переменной. Позже, при выполнении программы, его ьюжно будет и изменить, можно будет что-то записать в эту ячейху, но к началу выполнения программы в этой ячейке уже будет находиться данное значение. В простейшем и наиболее распространенном случае начальное значение баГповой переменной задается в виде числа с величиной от -128 до 255. Например: ВРЕЬ 1 ОРЕЬ 1 256-2 254) 17Ь а ВВ 254 В ВВ -2 С ПВ 17Ь и пв гхь и вв "*" Во втором случае ассемблер сам определит код указанного символа и запишек этот код в ячейку пючяти.
Ясно, что этот вариант лучше - он нагляднее и не тре. бует знания кодов символов, поэтому его обычно и используют на практике. По каждой из этих директив ассемблер отводит один байт под переменную и записывает в этот багге указанное число. Тжим образоы, к начачу выполнения программы переменная А будет иметь значение 254, переменная В - значение -2, а переменная С - значение 1Тш Операнд-число, естественно, переводится ассемблером в двоичную систему. При этом неотрипательные числа записываются в память как числа без знжа, а отрипательные числа записываются в дополнитетьном коде (см. комментарии к директивам). В связи с этим и получается, что в качестве операндов можно указывать числа от -128 до 255.
Отсюда же следует, что числа 254 и -2 будуг представлены в памяти одним и тем же байтом ОРЕЬ (это для нас данные числа различны, а для машины они одинаковы, и ей безразлично, что обозначает бып ОРЕЬ - число со знаком или без знака). В другом распространенном случае в качестве начального значения перемен. ной указывается символ. Такое значение ыожно задать двояко: либо указать чис. ловой код этого символа, либо указать сюч сиьшол в кавычках. Например, в си. стече кодировки АБСП код символа "*" равен 2АЬ, поэтому слелуюшие две директивы эквивалентны: эо Прсгрвммирсввиив ив явмвв вссвмблврв <ВЧ РС М+1 не следует понимать как сложение содержимого ячейки с именем М ( т.
е. числа 2) с числом 1. В ЯА запись вида <илы>Н< означает, что к адресу указанного имени надо прибавить (или отнять) число )<, в результате чего получится некоторый новый адрес, и вот уже по этому адресу и осуществляется доступ к пт<яти. Таким образом, данная запись означает сложение/вычитание адресов. Онвранд - строка Возможно еще одно сокращение в директиве РВ: если в ней несколько соседних операндов - символы, то их можно объединить в одну строку. Например, следующие две директивы эквивалентны: в пв вье <Зтл<етил<, что и в этом случае тип иыени равен 1 (Т1'РЕ 3 = ВУТЕ), т.
к, любая из этих директив является сокращением следующих трех директив: впв в пв ь вв 'с' а здесь ясно видно, что имя 3 обозначает только первый байт. Вопрос о том, объединять соседние символы в одну строку или нет, а если объеди>итгь то какие именно, решает сам автор программы. Например, нашу директиву люжно записать и так: В ПВ 'вЬ','с' илн В ПВ 'а','Ьс' Онвранд - конструкция нввтврвннк РЮР Рассмотрим еше одно возможное сокращение в записи директивы РВ.
Ловольно часто в директиве приходится указывать одинаковые операнды. Например, если л<ы хотим описать байповый массив К из 8 элементов с начальным значением 0 для каждого из них, то это люжно сделать так: н пв о,о,о,о,о,о,о,о Так вот, эту директиву можно записать и короче: к вв в лов<о) Здесь в качестве операнда использована так называемая конструкпия повторения, в которой сначача указывается коэффипиент повторения, затем - служебное слово Р1)Р (дпрйса<е, копировать), а за ним в круглых скобках - повторяемая величина.
В общем случае эта конструкния имеет следующий< вид: <рз Р2 . '' ра> где )< - константное выражение с положительным значением, п>=1, р - любой л допустимый операнд директивы РВ (в частности, это может быть снова кон эг Прсгреммирсеение не языке ассемблера IВМ рп Как и в случае директивы РВ, неотрипательные числа записываются в паьгять как числа без знака, а отрипательные числа - в дополнительном коде. Поэтому числа, которые могут быть заданы как операнды директивы 'ЕИУ, должны приналлежать отрезку [-3'з 2'е-1). Но здесь имеется и отличие от лирективы РВ. Напомним, что в ПК числа размером в слово хранятся в памяти в "перевернутом" виде.
Так вот, на ЯА такие числа записываются в нормальном, неперевернутом визе, а "переворачиванием" их занимается сщч ассемблер, поэтому по нашим двум директивщч пюгять заполнится следующим образом: 34 ГЕ ГГ В С учетом этого при программировании на ЯА можно в общем-то забыть о "перевернутом" представлении чисел в памяти ПК. Частныьг сл)чаезг рассматриваемого вида операнда директивы Ртт' может быть строка из одного или лвух символов, например: шов оз вг ов 1 Если указана строка из двух символов, тогда ассемблер берет коды указанных символов (в нашем случае - ЗОЬ (кол 'О') и 3!Ь (кол '1')) и образует из пих число- слово (3031Ь), которое и считается начальным значением описываемой переменной (51).
Но как и любое число размером в слово, данное значение будет записано в пшить в "перевернутом" виде. Если же в правой части директивы 0% указан один символ, тогла к нему слева приписывается символ с кодом О и дальнейшие действия ассемблера булуг такими же, как и в случае лвухсимвольной строки. Поэтому по нашим двум директивач пюгять будет заполнена следующим образом: 1 !$ В связи с тем, что операнлы-строки записываются в пюить в "перевернутом" виде, что в общем-то нс характерно для строк, то полобнью операнды редко указываются в директиве 01ьг. Адресное выражение В качестве операнла директивы Рзьг может быть )жазано алрссное выражение, т. е.
выреэкение, значением которого является алрес. Как записывшотся такие выражения, мы еще рассмотрим, а пока лишь отметим, что основной случай алресногс вырахжния - это ичя переменной или метка. Поэтому допустим такой пример: сов г о ов с вв Программирование ив языке ассемблере )ВЫ РС Конечно, такая особенносп задания начальных значений для переменных размером в двойное слово не очень-то приятна, но так уж устроен ЯА, и это надо учитывать. Адресное выражение Такой операнд задает абсолютный адрес. Как это делается, будет рассмотрено позже, в гл. ь Несколько ояврандов, конструкция новторвннл Возможный пример: вв 33 ввэ(т)р 12345Ь 2.4.
Директивы эквивалентности и присваивания Мы рассмотрели, как в ЯА описываются переменные. Теперь рассмотрим, как в этом языке описываются константы. Это делается с помощью директивы эквивалентности - директивы ЕЯ1) (ес)иа1, равно), имеющей) следующий синтаксис) <имя> вап <опвраал> Здесь обязательно долясно быть указано имя, должен быть и операнд, причем только один. Эта директива аналогична описанию константы в языке Паскаль: соавс <имя> <опвраии>) Директивой ЕЯП автор программы заяачяет, что указанному операнду он дает указанное иьи, и требует, чтобы все вхождения этого имени в текст програымы ассеыблер заменял на этот операнд. Например, если есть директива втьд вав " то ассемблер будет рассматривать предложение т вв втэк как предложение твв * Другими словами, указать имя ЗТАй и указать ми - это одно и то же.
Отметим, что директива Ес2)э' носит чисто информапионный характер, по ней ассемблер ничего не записывает в машинную программу. Поэтому директиву Еф) можно ставить в любое место программы - и между командами, и между описаниями переменных, и и других местах. Теперь рассмотрим, какиьс может быть операнд директивы ЕС11) и в каких случаях полезна эта директива. Яььа ассемблере. Лаеееьеме сведение 00 Олвралд - цыл Если в правой части лырективы указано имя регистра, переменной, константы и т. п» тогда имя слева обьяю)яа)ся синонимом данного имени и все последующие вхождения в текст просркчзгы этого югени-синонима ассемблер будет заыеиять на юш, указанное справа. Например: авяг В Кап Л с пя я' ; еавлвалеаелсг с Пи ь Имена-синонюсы обычно используются для введения более удобных, нага)злых обозначений.