В.Н. Пильщиков - Программирование на языке ассемблера IBM PC (1110551), страница 3
Текст из файла (страница 3)
Например, само по себе юш реп)стра АХ ни о чем не говорит, но если ыы используем этот регистр для вычисления кюсой-то суьпгы, то его ыожно обозначить Я)М: яои кпо ах и далее использовать это более наглядное юш Я)М. Отметим, что юш, указанное в правой части директивм Е)11), ьюжет быть описано в програь)ме как до этой директивы, так и после нее. Олераиг) - калсеьаигеиае выражение Примеры: Ы Кап ЬОО К Лол З*н Ь атал 'кйп Если в правой части директивы ЕС11) стоит константное аырвжение, тогда указанное слева имя принято называть именеы константы. Значением этой константы объявляется значение выражения. Напрюьер, Х - это константа со значением 100, К - со значением 199, а ВТАК - со значением ЗАЬ (зто код звездочхи в системе АЗСП). Все последующие вхождения в текст программы имени константы ассемблер будет замеюпь на значение этой константы.
Например, директива х ля и пОз(г) эквиеаченгна директиве Х пя ЬОО РОР12) Случаи, когда полезно применение констант, - такие же, как и а языках высокого уровня. Например, в качестве констант рекомендуется описывать размеры массивов, поскольку в таком случае лепсо настроить прогрючму на работу с ыассивом другого размера - для этого достаточно внести изменение лишь в директиву Е(Щ описывающую константу. Отметим, что если в константном выражении используются имена друпьх констант, то они должны быть описаны раньше данной директивы ЕО1), иначе Лимьюмиаи 36 Программирование нв венке ассемблере >ЛМ РС ассемблер, просматривающий текст прогрюгмы сверху вниз, не сможет вычислить значение этого выражения.
Олвранд любой другой текет Примеры: В ЕЯО 'ВВ Олвбллсь' ПХ ЕПВ Х+>Н-1> ВР еяп лоло Ртк В данном случае считается, что указанное имя обозначает операнд в том виде, кэк он записан (операнд не вычисляется). Именно на этот текст и будет заменяться каждое вхохдение данного имени в программу. Например, елелующие предложения слева эквивалентны предложениям справа АНВ ОВ 'Вв овлбллсь','!' Нва Х+>Н-1> глс ново Ртл 1вх) ЬНВ ОВ В, Нва ОХ хне вР 1Вх> <юоь> = <ковстввтвое вврвхевве> Эта директива определяет константу с именем, указанным в левой части, и с числовым значением, равным значению вырэхения справа.
Но в отличие от констант, определенных по директиве ЕОЦ данная константа может менять свое значение, обозначая в разных частях текста программы разные числа. Например: К 10 Л ОВ К к=к+э В ОВ К екввввлевтвоь А Ов 10 > ьхвиввлевтвоь в Ов 14 Подобного рода константы ьюхно испачьювать, например, ради "экономии имен": если в разных частях текста программы используются разные констюпы и области использования этих констант не пересекаются, тогда, чтобы не придумывать новые имена, этим константам можно дать одно и то же иьи Такой вариант директивы Е(Ю обычно используется для того, чтобы ввести более короткие обозначения для часто встречающихся длинных текстов.
Введя короткое иьи,мы дачее в програьше ьюжем им пользоваться, а ух ассемблер сам будет его заменя>ь на соответствующий текст. Отметим, что текст, указанный в правой части директивы Е( Н, должен быть сбадвнсирован по скобкам и кавычкам и не долхен содержать вне скобок и кавычек символа ";". Кроме того, поскольку текст не вычисляется, то в нем можно использовать как имена, описанные до этой директивы Е>>Ц так и имена, описанные после нее. Теперь рассмотрим еще одну директиву ЯА, похохую на директиву ЕОЦ - директ>иву присваивания: 40 Пропзаммироаание на языке ассемблера )ВМ РС Пример использования константного выражения с арифметическими операторами: к епв зо Х ВВ (3*к-1)/2 ВОР(т) ;массив ав 44 байтов Операндами арифметических операторов должны быль константные выражения.
Но здесь есть одво важное исключение: в ЯА разрешается вычитание одного адреса из другого и в результате получается число, а пе адрес. Пример: Х ВИ 1,2,3,4,5 тввт В1ХЕ Х ЕЦВ Х-Х ) В1ХЕ Х = 10 Вычитание алресов используется обычно для определения расстояния (числа байтов) между этими адресами. В нашем случае разность х'-Х показывает, сколько байтов занято всеми элементаыи л(ассива Х. Отметим олпу особенность арифметических операторов: все опи выполняются в области )б-битовых чисел, т. е.
от результата всегда берутся только последние 1б битов (остаток от деления на 2'4, на )ООООЬ), наприыер: (2*ООООЬ)к100Ь (12000Ь)/100Ь -> 2000ЬГ100Ь = 20Ь (а ае 120Ь) 2э о. Адресные выраженпа Значениями адресных выражений являются )6-битовые алреса. Все операции вал алресами выполняются по ьюдулю 2'а ()ООООЬ). К простейшим адресныьг выражениям относятся: метка (имя команды) и имя переменной, описанное в директиве ПВ, Озк' или ОО (значениями таких выражений яаиются алреса меток и имен); счетчик размещемия; он записывается как б и обозначает адрес того предложения, в котором он встретился.
При трансляции программы ассемблер следит за тем, в ячейку с каким адресом должен попасп машинпмй эквивалент очередного предложения програымы на ЯА; так вот, если мы хотим сослаться на этот адрес, то и пало указать 8. Отсюда следует, что в разных предложениях 5 обозначает разные адреса. Например, если алрес переменной А равен )ООЬ, то Имеем а ВИ В ) эавввааеатво Х ВИ 100Ь В ВИ 5 ; эававааевтно В ВИ 102Ь Чаше всего счетчик. размещению используется для вычисления размера памяти, занимаемой хаким-то массивом, например: Х ВИ 40 ВОР(т) я1хе х епп 5-х ; вххе х 00 Глава 3 ПЕРЕСЫЛКИ.
АРИФМЕТИЧЕСКИЕ КОМАНДЫ Мы переходим к изучению команд ПК и способов их записи в ЯА. В данной главе будут рассмотрены команды пересылки и арифметические команды. 3.1. Обозначение операндов команд При описании команд наы придется указывать, какие операндм в них допустимы, а какие - нет. Для сокращения подобного рода указаний мы введем сейчас обозначения, которыми затем будем пользоваться при описании команд. дтестонатождение олеранда Обозначение Зались в яд 18, 116, з32 г8, г16 и ш8, гп16, пз32 в команде в регистре общего назначения в сегментном регистре в ячейке пюгяти константное выражение иыя регистра СБ, !)8, 88, ЕЗ адресное выражение 3.2. Команды пересылки В ПК достаточно много команд пересылки, здесь мы рассмотрим толыго две из них - МОЧ и ХСНО.
Кроме того, рассмотрим оператор РТД. 3 '.1. Команда МОЧ В ПК есть машинные команды пересылки байта или слова (переслать одной командой двойное слово нельзя). Пересылаемая величина берется из команды, регистра или ячейпси пюгяти, а записывается в регистр или ячейку пюгяти (записывать в команду, естественно, нельзя). Таких команд много, но в ЯА все они записываются одинаково: Переслала (моче)з Иор орз,орз Непосредственные операнды (т. е. задаваемые в самой команде) мы будем обозначать буквой! (от !шшез)!аге, непосредственный), указывая за ней, сколько разрядов - 8 (байт), 16 (слово) или 32 (двойное слово) - опюдится на него в команде.
При этом отлзетим: запись !16 не означает, что операнд не может быть небольшим числом, в качестве !16 можно указать и операнд О, и операзш 32000, лищь бы он занимал не более 16 разрядов. В ЯА непосредственные операнды записываются в виде константных выражений. Регистры будеы обозначать бугсвой г (от ге81згег), указывая за ней требуемый размер регистра: г8 - это байтовые регистры (АН, А1., ВН и т. п.), а г16- регистры размером в слово (АХ, ВХ, 8! и т. п.). При этом буквой г мы обозначаем только регистры обпзего назначения, сепаентные же регистры мы будем обозначать как зг. Если операнд находится в пючяти, то в команде указывается едрес соответствувшей ячешси.
Такие операнды мы обозначаем буквой гп (от шешогу, память) с указанием размера ячейки. В ЯА эти операнды задаются адресными выражениями. Позтоыу при программировании на ЯА можно считать, что имеется только одна команда пересылки. Ассемблер, проанализировав указанные в этой символьной команде операнды, сам выберет нужную машинную команду пересылки, которую и запишет в формируемую им машинную программу. По коьганде МОЧ на место первого операнда пересылается значение второго операнда: ор1:мор2.
Флаги эта команда не меняет. Приыеры: Ьг 500 ; вь:-вл иот ьх,500 иот вь,вн В коьгацде МОЧ допустимы следующие комбинации операндов: ор2 ор! пересылка баГпов пересылка слов Из этой таблицы видно, что запрещены пересылки из одной ячейки лазити влругую, из одного сегментного репгстра в другой, запись непосредственного операнда в сегментный регистр. Это обуслоачено теы, что в ПК нет таких машинных коьишд. Если по ашоритму все же нужно такое действие, то оно реализуется в две коьганды, пересылкой через какой-нибудь несегментнмй регистр.
Например, записать число 100 в сепаентный регистр П8 мохпю таш нот ьх,100 мот ва,ьх Вяг 10О Отметим также, что командой МОЧ нельзя менять содержимое сегментного регистра СЗ. Это связано с тем, что регистры СЗ и 1Р определяют адрес той команды программы, которая должна быть выполнена следующей, поэтому изменение любого из этих регистров есть ничто иное, как операция перехода, а не пересылка. Команда же МОЧ не реазизует переход. Как известно, в ПК числа размером в слово хранятся в пшити в "перевернутом" виде, а в регистрах - в нормальном, неперевернутом.
Команда МОЧ учитывает это и при пересылке слов между пюштью и регистрами сама "переворачивает" их: 0 ВВ 1234Ь; Яг 34Ь, 0+1 ° 12Ь мот ьх,я г ьн 12Ь, ь1 34Ь По команде МОЧ ьюжно переслать как баГгг, так и слово. А как узнать, что именно - баГп или слово - пересылает команда? Не может ли получиться так, что мы хотели написать команду пересылки слова, а оказачось, что коьгагша пересы- "лиоюг-миоэи г8 ш8 г16 м (кроьге СЗ) ш16 48, г8, ш8 18, г8 116, г16, зг, ш16 г16, ш16 Пб, г16, ш Поросьихи. Лра4ооономохио хомаоды 4В 40 Программирование нз языке ассемблере )ВЫ РП ласт байт? Ответ такой: размер пересылаеьюй величины определяется по типу операндов, указанных в символьиой команде МО1). Более точно ситуация здесь следу)ощая.
Пусть, к примеру, иыеются такие описания перемеииых: х ВВ 2 ; ттРе х Втте Т вы 2 з ТТРЕ Т ВОЮ) иоч вл,в иоч х,о ИОЧ В1,0 иоЧ 1,0 байтовый рагыстр) как ымя байтовой парвмаввой) регистр размером в слово) как вмя ларамаввой-слова) ларасылка байта (ВЕ- то ва самое (Х осысвв ; парасвлка слова (В1- то ва самое (Т опвсав Отметим, что здесь по второму операнду (О) нельзя определить, какого ои размера: ноль л(ожет быть и бю1том (ООЬ), и словом (ООООЬ).