В.Н. Пильщиков - Программирование на языке ассемблера IBM PC (1110551), страница 6
Текст из файла (страница 6)
Действие же самой команды перехода заключаетсз в прибавлении этой величины к текущему значению репзстра 1Р. (Замечание. Если говорить точнее, то относительный адрес перехода отсчитывается не ст самой команды перехода, а от следующей за ней команды. Дело в том, что в ПК выполнение любой команды начинается с засылки в регистр 1Р адрес следующей по порядку команды и только затем выполняется собственно команда.
Поэтому в команде перехода относительный адрес будет прибавлятьсз к значению 1Р, которое уже указывает на следующую команду, а потому от этой следующей команды и приходится отсчитывать относительный адрес перехода. Однако в дачьнейшеьг мы не будем обращать вниыание на эту деталь, поскольку для ЯА она в общем-то не существенна.) В ПК имеются две ыашинные команды прямого перехода, в одной из которых относительный адрес перехода задается в виде баГпа (такэя команда называетсз коротким переходом), а в другой - в виде слова (это команда длинного перехода). В каждой из этих команд операнд рассматривается как целое со знаком (от -121 до +127 или от -2'з до 2'з-1), поэтому при сложении его с 1Р значение этого рс. гистра может как увеличиться, так и уменьшиться, т.
е. возможен и переход впс. ред, и переход назад. Естественно, возникает вопрос: в чем выгода ст того, что указывается не сая адрес перехода, а его расстояние от команды перехода". Это объясняется стрел. лением создателей ПК сэконоьцпь налгать, занимаемую командами перехода Если в команде указывать сам алрес перехода, то на него придется всегдз отводить слово (2 байта). Но практика показмвает, что в большинстве случыз переходы делаются на команды, расположенные недалеко от команд перехода поэтому разность между адресами этих двух команд, как правило, небольшая, да нее достаточно и баГгга.'Учитывая это, создатели ПК сделали так, чтобы именвз эта разность и указывалась в командах перехода, чтобы бачьшннство комис перехода можно было сделать на один байт короче. Однако эта экономия оборачивается бедой для прогрючмистов: при записз программы на машинном языке приходится вычислять относительные алреса пс реходов, что является крайне неприятным занятием.
Но, к счастью, ЯА избавлж' нас от этого занятия: програьшируя на ЯА, мы указываем лишь метку нужно' команды, а уж ассемблер сам подсчитывает разность между адресом этой мего и адресом команды перехода и подставляет эту разность в машинную команд)' 90 Пропэеммиреевиие ив венке вссембяерв 18М рп Итак, в ЯА один и тот же адрес можно записать разными способами. Однако при атом следует помнить, что используемая запись должна быть зквивалентно11 одной из трех основных форм записи таких адресов.
В частности, в записв не должно быть: суьщы двух адресов (А+В); суммы, одниз» из слагаемых которой является репгстр (ВХ+2); запрещенных сочетаний регистров ([31+ПЦ); регистров, не являющихся модификаторами (А[СХ], 2[ВЦ); имени или числа непосредственно за [] ([31]5, [ВХ]А). Кроме того, адрес не должен сводиться к числу ([5]), т. к. тогда зто будет константное вырюкение, а не адресное. В остальном ограничений нет, и каждый выбирает ту форму записи, что ем) больше нравится. Мы в дальнейшем будем использовать форму, в которой де скобок ставится иьга переменной, а остальные слагаемые указываются в квадрат.
ных скобках (например, А[31+3]). Такие записи похожи на привычные обозначе. ния переменных с индексами в языках высокого уровня (А[!+3]). И еще одно замечание. Адресные выражения с модификаторами можа испольювать при записи операндов команд и некоторых директив (ЕОЦ РТ1 и др.), но ни в коем случае нельзя указывать в директивах определения данных Например, директива х вв з(вх) является ошибочной, т. к. ассемблер обязан вычислить ее операнд еше на агап трансляции программы, чтобы подставить его значение в ячейку Х, но в зп вреьи значение репгстра 31, конечно, неизвестно. 5З.
Команды ЬЕА н Х[.АТ 5ЗЛ. Команда ЬЕА При испольювании репгстров-ьгодификаторов часто приходится записывав в них те или иные адреса. Пусть, к примеру, нам надо занести в регистр В1 адрес переменной Х: х пв 88 Чтобы сделать зто, можно завести еще одну переменную, значением котора является адрес Х: т вв х а затем переслать значение этой переменной в репютр ВХ: иот вх,т 02 Программирование нв языке весвмбявяв )ВМ РС ИОЧ ВХ,50 ЬЕЬ СХ,[ВХ+2] ;схл [ВХ]+2 50+2 52 ЬЕЬ Ог,[ОХ-З] ;Огл=аг-З [ае аоввюлввл ВОВ ОХ,З) 5З 'л.
Команда ХЬАТ Рассмотрим еще одну команду, связанную с модификацией адресов. Это тэх называемая команда перевода, перекодировки (правда, не очень понятно, откудл в ее мнемокоде взялась буква Х): Перекодировка (Еквав1азв): ХЬЬТ Действие этой команды заключается в том, что содержилюе бюпа памяти, щ. рес которого равен сумме текущих значений репютров ВХ и АЬ, записываетсл в регистр А[л АЬ:=байт по адресу (ВХ+АЬЬ Флюи не меняются. Колла)ща ХЬАТ используется для перекодировки символов. Предпалагаетсг, что имеется таблица (байтовый массив) размеров до 25б байтов, 1-й элемент ко торой трактуется как новый код символа с кодом 1.
Начальный адрес этой таблз. цы должен находиться в регистре ВХ, а исходный код (1) перекодируемого сия. вола - в регистре АЬ. Команда присваивает регистру А1. новый код символа, взь тый из ]-го элеыента таблицы. В качестве примера рассллатршг, как с помощью этой команды можно преаб разовать любую шестнадцатеричную цифру-число (ат О до 15) в цифру-символ Для этого определим в программе таблицу [)]О]б, перечислив в ней все символе изображающие шестнадцатеричные цифры: 01016 ОВ '01234567взаВСОЕЕ';01016[0..15] Пусть в регистре АЬ находится число от О до 15 (скажем, 14).
Тогда записав в этот регистр соответствующий символ-цифру ('Е') можно так: ЬЕХ ВХ,ОГВ16 ГВХ - ва аачаяе 01016 хьхх )аь! 01016[аь] 5.4. Структуры Мы рассмотрели, как на ЯА описываются и обрабатываются массивы. Тепер рассмотрим реализацию другого составного типа данных, который в языке Пв качь называют записью. Сразу отметилг, что в ЯА записи принято называть стр)в турами, поэтому в дальнейшем мы будем называть их талька структурами.
5А.]. Описание типа структуры Структура - это составной абьект, заниыающий несколько соседних ячеек Ю )гати. Компоненты структуры называются полями, они могут быть разного твя (размера): например, одно поле может быть байтоы, другое - словом и т. д, Паз именуются, доступ к полям осуществляется по именам. Прежде чем использовать структуру, надо описать ее тип - указать, скальке ней пачей, каковы имена у полей и т. д. Описание типа структуры выглядит тев ВВ Прогреыыирояение на языке ассемблера!ВЫ РС <лмл перемолкой-структурм>.
<лмл лоле> аналогичную обозначению поля в языке Паскаль. Возмоккмй пример: ОТЗ.О Тжая конструкши обозначает ту ячейку памяти, которую занимает указанное поле указанной переменной. Встречая эту конструкцию, ассемблер заменяет ес на адрес данной ячеггкн. Прн этом тнп (размер) этого адреса считается равныв типу данного поля, например: ТУРЕ 0Т2.У = ТЧОИ0. Рассмотрны такую задачу: если в переменной 0Т1 хранится мартовская дать, то требуется записать сюда дату следующего дня года. Решение этой задаче на ЯА записывается так: СМР ОТ].И,З ЗМЕ Ргн СМР ОТ1.О,З1 Юв АРД1 1МС ВТ1.О ЗМР Р1М АРЕ1г МОЧ ОТ1.Н,4 МОЧ ОТ1.О,1 Рхн: ;ле март -> Тдз 131 марка -> арк1 ;следуемой деаь ъ мерке !замела 31 марте ла 1 апреля 5.4.4.
Уточненгш Мы рассказачн об основных средствах ЯА для работы со структурами. Тепер рассмотрим некоторые дополнительные возыоещсстн и кое-что уточним. Тил ииели структуры Ассемблер приписывает югенн типа структуры и имени структуры тм (размер), равный числу бюттов„занюгаемых этой структурой. Напрюгер: ттРТ ОАте тхРе От1 тхРе ОЧ2 ттРе Отв 4 В связи с этим присванвание 0ТУлм0Т1, если немелательно по кжой-лвд причине явно указывать размер этих структур, ыозгно реализовать тж: ГСХ: размер структур тале ВАТЕ гзю е ;лобайтозел лереемлке ОТ1 => ОТ2 моч сх~ттРе Вьте моч вт,о ьг иоч Аь,вхте Ртд Отз(ат] меч Втте Рте ВР2(аг],АО 5.4З. Ссылки на поля структур Описав тнп структуры н переменные этого типа, мы получаем право работать с этими переменными-структурами.
Кж единое целое структуры обрабатываютсз довольно редко, обычно они обрабатываются по полям. Так вот, чтобы сослатьсз на поле структуры, надо использовать конструкцию вида 126 Прсграммирсеание на языке ассембяера 1ВМ РС не получился адрес, больший максимально допустимого. Таким образом, более точная формула вычисления абсолютного адреса такова: Аабс = 1ансс + 16*[от]) поЬ 2" Отметим, что сегментирование исполнительного адреса происходит, только если команда осуществляет доступ к паьити. Если же в команде не предусмотрено обращение к памяти, то сегментный регистр не учитывается.
Скажем, команда 1.ЕА г16,А не обращается к лазити, поэтому адрес А не будет сегментироваться, т. е. по этой команде выполняется операция г16:=Анси, а не операция г16:=Аабс. И, наконец, рассмотрим еше одну, наиболее интересную особенность сегментирования адресов в ПК. 7.1.3. Сегментные регистры но умолчанию Если проанализировать реальные машинные программы, то можно заметить, 'по в них в общем-то указываются адреса всего из трех областей памяти - сегмента команд, сегмента данных и сегмента стека Например, в команлат перехода всегда указываются адреса других команд, т.
е. это ссылки на сегмент команд - ту область памяти, где располагаются команды программы. В командах, работающих со стеком, естественно, указываются адреса из сегмента стека - области памяти, занимаемой стеком. В остальных же команды (пересылках, арифметических и т. п.) указываются, как правило, адреса ю сегмента данных - той области памяти, где расположены переменные, массивы и другие данные программы. С учетом этой особенности реальных программ в ПК принят ряд со.