12_Макросредства языка Ассемблер (В.Г. Баула - Введение в архитектуру ЭВМ и системы программирования), страница 6
Описание файла
Файл "12_Макросредства языка Ассемблер" внутри архива находится в папке "В.Г. Баула - Введение в архитектуру ЭВМ и системы программирования". PDF-файл из архива "В.Г. Баула - Введение в архитектуру ЭВМ и системы программирования", который расположен в категории "". Всё это находится в предмете "практика расчётов на пэвм" из 1 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Просмотр PDF-файла онлайн
Текст 6 страницы из PDF
Необходимо понять, что на этапе компиляции значение есть не у переменной с именем X, а только у имени переменной X (значение имени X равно адресу этой переменной в соответствующем сегменте).Кроме того, как мы знаем, на этапе компиляции почти все имена имеют тип, например, наше имя Xимеет тип word=2).В следующем примере мы покажем, как макроопределение может обрабатывать макрокоманды спеременных числом фактических параметров. Задачи такого рода часто встают перед программистом. Пусть, например, в программе надо часто вычислять максимальное значение от несколькихзнаковых целых величин в формате слова. Для решения этой задачи в нашем Макроассемблере можно написать макроопределение, у которого будет только один формальный параметр, на место которого будет, однако, передаваться список (возможно пустой) фактических параметров.
Такой список внашем Макроассемблере заключается в угловые скобки. Пусть, например, макроопределение должновычислить и поместить на регистр ax максимальное значение из величин bx,X,-13,cx, тогда нуж-1Любознательные студенты могут попробовать диагностировать такого рода ошибки при помощи макроцикла irpc, который мы вскоре рассмотрим.15но вызвать это макроопределение с помощью такой макрокоманды (дадим этой макрокоманде имяmaxn):maxn <bx,X,-13,cx>Здесь у макрокоманды задан один фактический параметр (одна строка из 13 символов, включая и угловые скобки), который, однако, мы в макроопределении будем трактовать как список, содержащий вугловых скобках четыре "внутренних" параметра.Сделаем спецификацию нашей макрокоманды. Мы будем допускать, чтобы некоторые параметры из списка опускались (т.е.
задавались пустыми строками). При поиске максимума такие пустыепараметры будем просто игнорировать, и не выдавать при этом никакой диагностики. Далее необходимо договориться, что будет делать макрокоманда, если список параметров вообще пуст. В этомслучае можно, конечно, выдавать диагностику о фатальной ошибке и запрещать генерацию объектного модуля, но мы поступим более "гуманно": будем в качестве результата выдавать самое маленькое знаковое число (в шестнадцатеричной форме записи это 8000h).Ниже приведён возможный вид макроопределения для решения этой задачи. Наше макроопределение с именем maxn будет вызывать вспомогательное макроопределение с именем cmpax. Этовспомогательное макроопределение загружает на регистр ax максимальное из двух величин: регистра ax и своего единственного параметра X.; Вспомогательное макроопределениеcmpax macro Xlocal Lcmpax,XjgeLmovax,XL:endm; Основное макроопределение; Максимум переменного числа аргументовmaxn macro Xmovax,8000h; MinIntirp i,<X>ifnb <i>cmpax iendifendmendmПоясним работу макроопределения maxn, однако сначала, как мы обещали ранее, нам надо существенно уточнить правила передачи фактического параметра (строки символов) на место формального параметра.
Дело в том, что некоторые символы, входящие в строку – фактический параметр, являются для Макропроцессора служебными и обрабатываются по-особому, такие символыназываются в нашем Макроассемблере макрооператорами. Ниже приведено описание наиболееинтересных макрооператоров, полностью их необходимо изучить по учебнику [5]. Если фактический параметр заключён в угловые скобки, то они считаются макрооператорами выделения, они заставляют рассматривать заключённый в них текст как единое целое, даже если в нём встречаются служебные символы. Обработка макровыделения заключается в том, что парные скобки отбрасываются при передаче фактического параметра на место формального. Обратите внимание, что отбрасывается только одна (внешняя) пара угловых скобок, если внутри фактического параметра есть ещё угловые скобки,то они сохраняются. Символ восклицательного знака (!) является макрооператором, он удаляется из фактического параметра, но при этом блокирует (иногда говорят, – экранирует) анализ следующего за ним символа на принадлежность к служебным символам (т.е.
макрооператорам). Например, фактический параметр <ab!!+!>> преобразуется в строку ab!+> ,именно эта строка и передаётся на место формального параметра. Это один из способов,как можно передать в фактическом параметре сами служебные символы.16 В том случае, если комментарий начинается с двух символов ;;, то это макрокомментарий, такой комментарий, в отличие от обычного комментария (начинающегося однимсимволом ;) не переносится в макрорасширение. Символ & является макрооператором, он удаляется Макропроцессором из обрабатываемого предложения (заметим, что из двух следующих подряд символов & удаляется толькоодин). Данный символ играет роль лексемы – разделителя, он позволяет выделять в текстеимена формальных параметров макроопределения и переменных периода генерации.
Например, пусть в программе есть такой макроциклK=1irp i,<l,h>K=K+1mov a&i,X&K&iendmПосле обработки этого макроцикла Макропроцессор подставит на его место в программуследующие строки:mov al,X2lmov ah,X3h Символ % является макрооператором, он предписывает Макропроцессору вычислить следующее за ним арифметическое выражение и подставить значение этого выражениявместо знака %. Например, после обработки предложенийN equ 5K=1M equ %(3*K+1)>NБудут получены предложенияN equ 5M equ 4>NРазберём теперь выполнение макроопределения поиска максимума от нескольких аргументовmaxn на примере макрокомандыmaxn <-13,,bx,Z>При передаче фактического параметра-строки <-13,,bx,Z> крайние угловые скобки будут отброшены, поэтому в макроцикле irp на место формального параметра X (внутрь угловых скобок)будет подставлена строка символов -13,,bx,Z.
Таким образом, макроцикл принимает следующийвид:irp i,<-13,,bx,Z>ifnb <i>cmpax iendifendmВ теле этого макроцикла располагается условный макрооператор с именем ifnb (if not blank), онпроверяет свой параметр и вырабатывает значение true, если этот параметр не является пустойстрокой символов. Таким образом, получается, что в теле макроцикла выполняется условный макрооператор, который только для непустых элементов из списка цикла вызывает вспомогательное макроопределение cmpax.
Единственным назначением этого вспомогательного макроопределения является локализация в нём имени метки L, которая таким образом получает уникальное значение длякаждого параметра из списка цикла.Обратите внимание, что наше макроопределение будет неправильно работать для макрокоманд,содержащих в списке параметров регистр ax, напримерmaxn <-13,ax,bx,Z>Мы, однако, уже знаем, как это можно исправить, усложнив макроопределение.Макроопределения с переменным числом параметров являются достаточно удобным средствомпри программировании многих задач. Аналогичный механизм (но с совершенно другой реализацией,чем в макросредствах Ассемблера) есть, например, в языке высокого уровня С, который допускаетнаписание функций с переменным числом фактических параметров.
Правда, для функций языка С17фактических параметров должно быть не менее одного, и значение этого первого параметра обязанокаким-то образом однозначно задавать для функции общее число фактических параметров.Напомним, что в языке Паскаль программист не может писать свои собственные процедуры ифункции с переменным числом параметров, так как, по мнению автора этого языка Н. Вирта, этоснижает надёжность программирования. В то же время совсем обойтись без такого очень удобногосредства Паскаль не мог: в нём есть стандартные процедуры с переменным числом параметров,например, это процедуры ввода/вывода Read и Write.Теперь мы познакомимся с использованием механизма настройки макроопределения на типыпередаваемых ему фактических параметров. Здесь имеется в виду, что хотя с точки зрения Макропроцессора фактический параметр – это просто строка символов, но с точки зрения самого Ассемблера, если параметр содержит некоторое имя, то у этого параметра может быть тип.
Например, фактическим параметром может быть имя длинной или короткой целой переменной, константы и т.д. и ясно, что для обработки операндов разных типов в Ассемблере требуются и различные форматы команд. Другими словами, программисту может понадобиться внутри макроопределения выбрать(средствами условной генерации) один из нескольких форматов команды (например, команды сложения) для обработки операндов разных типов, переданных в это макроопределение в качестве фактических параметров.Как мы помним, для стандарта языка Паскаль у процедур и функций должно соблюдаться строгое соответствие между типами формальных и фактических параметров.1 А как быть программисту,если, например, ему надо написать функцию для поиска максимального элемента массива, причёмнеобходимо, чтобы в качестве фактического параметра этой функции можно было бы передаватьмассивы разных типов (с целыми, вещественными, символьными, логическими и т.д.
элементами)?На языках высокого уровня хорошо решить эту задачу практически невозможно.2Сейчас мы увидим, что макросредства предоставляют программисту простое и элегантное решение, позволяющее настраивать макроопределение на тип фактических параметров. Рассмотримследующую задачу. Предположим, что нам в программе необходимо суммировать массивы короткихи длинных целых чисел. Для реализации такого суммирования можно написать макроопределение,например, с таким заголовком:SumMas macro X,NВ качестве первого параметра X этого макроопределения можно задавать массивы коротких илидлинных знаковых целых чисел, количество элементов в этом массиве указывается во втором параметре N.