Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

А. Структура отчета по курсовой работе

Поиск

Задание.

В соответствии с вариантом формулируется задание по курсовой

работе.

Цель работы.

Постановка задачи.

В этом разделе требуется формализовать задачу, указать возможные

ограничения на ее решение и т.п.

Анализ и разработка алгоритма.

Основной раздел отчета. Должен отражать результаты анализа

возможных вариантов решения задачи и выбора среди них наиболее

рационального. Обосновывается выбор структур данных и основных

операций над ними. Приводятся результаты моделирования

программ-прототипов (если они использовались для разработки

алгоритма). Определяются источники и форматы исходных данных и

содержание вывода программы.(8-10 стр.)

Алгоритм программы.

В этом разделе приводится блок-схема алгоритма программы.

Текст программы для ГМ.

Здесь обосновывается выбор команд и директив для описания данных ГМ. Приводится текст программы для ГМ с комментариями.

 

 

Разработка алгоритмов макросов.

Приводится обоснование выбора и описание алгоритмов макросов (макроопределений) и их листинг.

Результаты моделирования программы на реальной ЭВМ.

Должны быть приведены результаты тестирования программы с различными наборами данных, в том числе и с некорректными данными.

Выводы.

Приводятся комментарии к результатам и рекомендации к дальнейшему совершенствованию программы.

Литература.

В. МАКРОСРЕДСТВА

Макроязык

Нередко бывает полезным предварительное (до начала трансляции) преобразо­вание текста программы. Например, может потребоваться, чтобы какой-то фраг­мент программы был продублирован несколько раз или чтобы в зависимости от некоторых условий в тексте программы были сохранены одни фрагменты и уда­лены другие. Подобную возможность предоставляют так называемые макросред­ства. Расширение языка ассемблера за счет этих средств обычно называют макроязыком.

Программа, написанная на макроязыке, транслируется в два этапа. Сначала она переводится на, так сказать, чистый язык ассемблера, т.е. преобразуется к виду, где нет никаких макросредств. Этот этап называется этапом макрогенерации, его осуществляет специальный транслятор - макрогенератор. На втором этапе полу­ченная программа переводится на машинный язык. Это этап ассемблирования, его осуществляет ассемблер.

Как видно, трансляция программы, написанной на макроязыке, занимает больше времени, чем трансляция программы на "чистом" языке ассемблера. Но зато макро­язык предоставляет больше возможностей, чем просто язык ассемблера, и потому писать программы, особенно большие, на макроязыке проще.

Макрогенератор и ассемблер могут взаимодействовать двояко. Во-первых, они могут действовать независимо друг от друга: сначала текст программы обрабаты­вает макрогенератор и только затем начинает работать ассемблер. Такой способ взаимодействия достаточно прост для понимания и для реализации и используется довольно часто, однако у него есть серьезный недостаток: макрогенератор, рабо­тая до ассемблера, не может воспользоваться информацией, извлекаемой из тек­ста программы ассемблером. Например, в макросредствах нельзя использовать то, что после директивы

n EQU 10

имя N обозначает число 10, т. к. эта директива относится к "чистому" языку ассемблера и потому будет обработана только ассемблером. Из-за подобного рода ограничений приходится усложнять макроязык.

Во-вторых, макрогенератор и ассемблер могут действовать совместно, чередуя свою работу: первым каждое предложение программы просматривает макро­генератор; если это конструкция собственно макроязыка, то макрогенератор соответствующим образом преобразует ее в группу предложений "чистого" языка ассемблера и тут же передает их на обработку ассемблеру, а если это обычное предложение "чистого" языка ассемблера, то макрогенератор сразу передает его ассемблеру. В таких условиях в конструкциях макроязыка уже можно ссылаться на объекты (например, константы) "чистого" языка ассемблера.

При "чередующемся" способе взаимодействия макрогенератора и ассемблера они фактически являются не двумя независимыми трансляторами, а частями одного транслятора, который принято называть макроассемблером.

Именно такой макроассемблер используется в рассматриваемой нами системе МАSМ. Этим и объясняется полное название ее входного языка - язык макроассемблера (macroassembler language, МАSМ). Однако в дальнейшем мы по-прежнему будем называть его языком ассемблера (сокращенно - ЯА), используя термин "макроязык" для обозначения только набора макросредств, а термин "макрогенератор" для обозначения той части макроассемблера, что занимается обработкой этих макросредств. Кроме того, термином "окончательная программа" мы будем называть ту программу, которая получается после работы макрогенератора, которая затем переводится (собственно) ассемблером на машинный язык и выполняется.

Блоки повторения

Иногда в некотором месте программы приходится выписывать несколько раз подряд один и тот же (или почти один и тот же) фрагмент, и хотелось бы, чтобы мы сами выписывали этот фрагмент только раз, а макрогенератор размножал его нужное число раз. Такая возможность предусмотрена в ЯА, и реализуется она с помощью блоков повторения (reрeat blocks).

Блок повторения имеет следующую структуру:

<заголовок>

<тело>

ENDM

Здесь <тело> - любое число любых предложений (в частности,ими могут быть снова блоки повторения), а ENDM - директива, указывающая на конец тела и всего блока повторений. Встречая в исходном тексте программы такой блок, макрогенератор подставляет вместо него в окончательную программу несколько копий тела. При дублировании тело может выписываться без каких-либо изменений, а может копироваться и с модификациями. Как именно происходит дублирование, сколько копий создается - все это зависит от заголовка блока. Имеется три раз­новидности заголовка, в связи с чем различают три варианта блока повторения:

REPT -блоки, IRP -блоки и IRPC -блоки.

REPT-блоки

Этот тип блоков повторения записывается следующим образом:

REPT k

<ТЕЛО>

ENDM

Здесь k - константное выражение с неотрицательным значением. Это выражение должно быть таким, чтобы можно было вычислить его сразу (например, в нем не должно быть ссылок вперед). Вычислив значение k, макрогенератор создает k точных копий тела блока и подставляет их в окон­чательный текст программы. Например, по блоку

rерт 3

SНR АХ,1

ENDM

будет построен следующий фрагмент окончательной программы:

SНR АХ,1

SНR АХ,1

SНR АХ,1

Другой пример (слева указан фрагмент исходной программы, построенный по нему фрагмент окончательной программы):

N EQU 6 N EQU 6

REPT N-4 DB 0,1

DB 0,1 à DW?

DW? DB 0,1

ENDM DW?

Отметим, что в блоках повторения довольно часто используется директива присваивания (=). Например, описать 100-байтовый массив X, элементы которого имеют начальные значения от 0 до 99, можно так (справа указан текст окончательной программы, который фактически эквивалентен директиве X DB 0,1,2,3,...,99):

X DB 0 X DB 0

K=0 K=0

REPT 99 K=K+1

K=K+1 à DB K 99 таких пар

DB K K=K+1

ENDM DB K

...

IRР-блоки

Блоки повторения этого типа имеют следующий вид:

IRP p,<v1,.... vk>

<тело>

ENDM

(Замечание: уголки в записи <v1,...,vk> - это явно указываемые символы, а не метасимволы.)

Здесь р - некоторое имя, оно играет роль формального (фиктивного) параметра и может использоваться в предложениях тела. vi - это фактические параметры; это любые тексты (возможно, и пустые), но, чтобы не было путаницы, они должны быть сбалансированы по кавычкам и не должны содержать запятые, точки с запятой и уголки вне кавычек Параметры vi перечисляются через запятую, а вся их совокупность обязательно заключается в угловые скобки.Встречая такой блок, макрогенератор заменяет его на k копий тела (по одной на каждый фактический параметр), причем в i -й копии все вхождения имени р заменяются на vi. Например:

 

 

IRP REG,<AX,CX SI> PUSH AX

PUSH REG à PUSH CX

ENDM PUSH SI

Отметим, что формальный параметр локализуется в теле блока (им нельзя пользоваться вне блока) и может быть любым именем. Если оно совпадает с именем другого объекта программы, то в теле блока оно обозначает именно параметр, а не этот объект. Например, в блоке

IRP BX,<1,5>

ADD AX,BX

ENDM

имя ВХ обозначает параметр, а не регистр, поэтому по данному блоку будет построен следующий фрагмент окончательной программы:

ADD AX,1

ADD AX,5

Замены формального параметра на фактические - это чисто текстуальные подстановки, без учета смысла: просто один участок текста (р) заменяется на другой (vi). При этом параметром р можно обозначить любую часть предложения (в частности, участки комментария) или даже целиком все предложение (однако два и более предложений он не может обозначать), лишь бы после замены р на vi получались правильные предложения ЯА. Например:

IRP Q,<DEC WORD PTR, L: INC> DEC WORD PTR W

Q W JMP M2

JMP M2 à L: INC W

ENDM JMP M2

Отметим также, что в теле блока повторения заменяется только формальный параметр, другие имена (например, имена констант) переносятся в копии тела без изменений. Например:

N EQU 1 à N EQU 1

IRP P,<A,B> A EQU N (но не A EQU 1)

P EQU N B EQU N

Другие особенности записи формальных и фактических параметров будут рассмотрены в разд. 2.4.

IRPC-блоки

Блоки этого типа записываются следующим образом:

IRPC р,s1...sk

<тело>

ENDM

И здесь р - формальный параметр, а вот si- это символы. Это могут быть любые символы, кроме пробелов и точек с запятой (считается, что с точки с запятой начинается комментарий, а пробел заканчивает операнд; если надо указать точку с запятой или пробел, то всю последовательность символов следует заключить в угловые скобки - см. разд. 2.4). Встречая IRPC-блок, макро­генератор заменяет его на k копий тела блока (по одной на каждый символ), причем в i-й копии все вхождения пар-ра р будут заменены на символ si.

Пример:

IRPC D,17W ADD AX,1

ADD AX,D à ADD AX,7

ENDM ADD AX,W

Макрооператоры

При использовании блоков повторения (и макросов, которые будут рас­смотрены чуть позже) возникает ряд проблем с записьюих формальных и факти­ческих параметров. Эти проблемы решаются с помощью так называемых макрооператоров - операторов, разрешенных к применению только в конст­рукциях макроязыка.

Макрооператор &

Рассмотрим следующий блок повторения и построенные по нему копии:

IRP W, <VAR1,VAR6> VAR1 DW?

W DW? à VAR6 DW?

ENDM Здесь параметр W обозначает имя переменной целиком. Но фактические имена (VAR1 и VAR6) различаются лишь последним символом, поэтому было бы разум­нее объявить параметром только этот символ, а не все имя. Но если так и сделать:

IRP W,<1, 6>

VARW DW?

ENDM

 

то получится неоднозначность: становится непонятным, когда W обозначает формальный параметр, а когда саму букву W (почему в VARW надо W заменять на 1 и 6, а в DW не надо?). Во всех предыдущих примерах мы не сталкивались с такой проблемой, т. к. формальные параметры легко выделялись из окружаю­щего текста благодаря ограничителям (пробелам, запятым и т. п.), стоящим слева и справа от них. Но если рядом с параметром стоит имя или число, то границы параметра становятся неопределяемыми. В подобной ситуации следует между параметром и соседним с ним числом или именем поставить символ & (А&W, 1&W&В и т. п.). Например, наш блок повторения должен быть записан следующим образом:

IRP W,<1, 6>

VAR&W DW?

ENDM

Назначение знака & - указать границу формального параметра, выделить его из окружающего текста, при этом в окончательный текст программы он не попадает. (Если & поставить не около параметра, то он будет просто опущен). Макрооператор & используется не только тогда, когда формальный параметр "сливается" с соседними именами и числами, но и когда его надо указать внутри строк. Дело в том, что макрогенератор игнорирует вхождения формального параметра в строки, и чтобы обратить его внимание на эти вхождения, перед параметром в строках надо ставить знак & (а если не ясна его правая граница, то & надо указывать и после параметра). Например:

IRPC A,”< DB ‘A, “, “B’

DB ‘A, &A, &A&В' à DВ 'А, <, < В'

ENDM

И ещё одна особенность макрооператора &: если рядом поставить несколько знаков &, то макрогенератор удалит только один из них. Это сделано специально, учитывая возможность вложенности блоков повторений (и/или макросов). Например:

 

IRPC P1,AB IRPC P2,HL INC AH

IRPC P2,HL à INC A&P2 à INC AL

INC P1&&P2 ENDM INC BH

ENDM IRPC P2,HL INC BL

ENDM INC B&P2

ENDM

Встретив в тексте исходной программы блок повторения, указанный в левой колонке, макрогенератор сначала создаст первую копию тела внешнего блока, в котором все вхождения его формального параметра Р1 будут заменены на символ А(см. три верхние строчки средней колонки). При этом из двух подряд стоящих в команде INC знаков & будет удален только один, и оставшийся знак & будет отделять формальный параметр Р2 внутреннего блока от стоящей слева буквы А (если бы был только один знак &, то эта команда имела бы вид INC АР2, и потому запись АР2 не воспринималась бы как состоящаяиз двух частей - А и Р2). Поскольку в полученной копии остались конструкции макроязыка, то макрогенератор продолжает свою работу (это общее правило: макрогенератор работает, пока не получится текст на "чистом" языке ассемблера) и "раскручивает" внутренний блок, получая уже окончательный текст (см. две верхние строчки в правой колонке). Далее создается вторая копия внешнего блока, которая обрабатывается аналогично.

Макрооператор <>

Как было сказано, фактические параметры IRP-блока не должны содержать запятые, точки с запятой и уголки, а во втором операнде IRРС-блока нельзя указывать пробелы и точки с запятой. Эти ограничения связаны с тем, что иначе возможна путаница: например, если внутри фактического параметра IRР-блока указать запятую (скажем: 1,2), тогда будет непонятным, что означает эта запись- то ли два параметра, разделенных запятой, то ли один параметр. Так вот, если надо нарушить указанные ограничения, тогда весь фактический параметр IRР-блока или всю последовательность символов в IRРС-блоке надо заключить в угловые скобки (например: <1,2>), причем текст внутри этих скобок должен быть сбалансирован по уголкам. При этом считается, что внешние угловые скобки не относятся к параметру или последовательности, что они лишь указывают их границы.

Примеры:

IRP VAL, <<1, 2>, 3> à DB 1, 2

DB VAL DB 3

ENDM

IRPC S, <A; B> à DB ‘A’

DB ‘&S’ DB ‘;’

ENDM DB ‘B’

Макрооператор!

А что делать, если внутри фактического параметра надо указать непарный уголок или кавычку? Для задания этих и других спецсимволов (вне или внутри угловых скобок) предусмотрен следующий макрооператор:

! <символ>

Смысл этой записи: сам символ! "погибает" (не переносится в окончательный текст); но следующий за ним символ трактуется как обычный символ, а не как символ, играющий какую-то специальную роль. Например:

IRP X, <A!>B, Привет!, ПК!!> DB ‘A>B’

DB ‘&X’ à DB ‘Привет, ПК!’

ENDM

Макрооператор! можно использовать только при записи фактических параметров IRP-блоков (и макросов), тогда как в последовательности символов (во втором операнде) IRРС-блока знак! рассматривается как обычный символ. Указывать в этой последовательности уголки можно сколько угодно раз, если эта последовательность не начинается с открывающей угловой скобки, а если начинается - пока нет баланса угловых скобок.

 

Макрооператор %

В макроязыке есть еще один макрооператор, используемый при записи фактических параметров IRP-блоков (и макросов):

% <константное выражение>

Встретив такую конструкцию в фактическом параметре, макрогенератор вычисляет указанное выражение и подставляет его значение вместо всей этой конструкции. Например:

K EQU 4

... DW K+1

IRP А,<К+1,%К+1,W%К+1> à DW 5

DW A DW W5

ENDM

Отметим, что вложенность макрооператоров % не допускается (например, в конструкции %5-%К будет зафиксирована ошибка "неописанное имя %К") и что концом константного выражения считается первый символ (например, запятая, угловая скобка или знак равенства), который не может по синтаксису входить в константные выражения (например, при значении 4 у константы К параметр %К-1+К=К будет преобразован в 7=К).

Отметим также, что в последовательности символов (во втором операнде) IRPC-блока знак % рассматривается как обычный символ, а не как макрооператор.

Макрооператор;;

Если в теле блока повторения (и макроса) имеются комментарии (в конце каких-то предложений или как самостоятельные предложения), то они переносятся во все копии блока. Однако бывает так, что комментарий полезен при описании самого блока повторения, но совершенно не нужен в его копиях. В таком случае следует начинать комментарий не с одной точки с запятой, а с двух - такие комментарии не копируются. Например:

IRР R,<АХ,ВХ>;восстановить АХ

;;восстановление регистров POP AX

;восстановить R à; восстановить ВХ

РОР R;;стек ==> R POP BX

ЕNDМ

 

Макросы

С помощью блока повторения один раз описывается некоторый фрагмент программы, который затем многократно копируется макрогенератором. Но блоки повторения можно использовать, только если эти копии должны быть расположены рядом друг с другом. А что делать, если фрагмент программы должен повторяться, но в разных местах программы? В этом случае используются макросы: специальным образом описывается этот фрагмент программы (это и есть макрос) и ему дается имя, а затем в нужных местах программы вы­писывается ссылка на этот макрос (указывается его имя); когда макрогенератор просматривает текст программы и встречает такую ссылку, то он вместо нее подставляет в окончательный текст программы сам макрос - соответствующий фрагмент программы; и так делается для каждой ссылки на макрос, в каком бы место программы она ни встретилась.

При использовании макросов применяется следующая терминология. Описание макроса называется макроопределением, ссылка на макрос - макрокомандой, процесс замены макрокоманды на макрос - макроподстановкой, а результат такой подстановки - макрорасширением.

113.1. Макроопределения

Описание макроса, т. е. макроопределение, имеет следующий вид:

<имя макроса> МАСRО <формальные параметры через запятую>

<тело макроса>

ЕNDM

Два конкретных примера:

 

SUM МАСRО Х,Y;Х:=Х+У VAR MACRO NM, TP, VL

MOV АХ, Y NM D&TP VL

ADD X, АХ ENDM

ENDM

Первая строка макроопределения - это директива МАСRО, которую принято называть заголовком макроса. В ней, во-первых, указывается имя, которое мы дали макросу, а во-вторых, через запятую перечисляются формальные параметры макроса. Необходимость в параметрах вызвана тем, что в общем случае макрос должен копироваться не в неизменном виде, а с некоторыми модификациями; параметры и обозначают те величины, которые влияют на эти модификации. Фор­мальным параметрам можно давать любые имена, эти имена локализуются в теле макроса; если имя параметра совпало с именем другого объекта программы, то внутри макроопределения под этим именем понимается параметр, а не этот объект.

Тело макроса - это тот фрагмент программы, который затем и будет многократно копироваться. Тело может состоять из любого число любых предложений, в которых, естественно, можно использовать формальные параметры макроса. Как и в блоках повторения, формальные параметры могут обозначать любые части предложений тела. При этом, если рядом с параметром надо указать имя либо число или если параметр надо указать внутри строки, то следует использовать макрооператор & (см. D&ТР в макросе VAR). В теле макроса можно использовать комментарии, начинающиеся с двух точек с запятой. Завершает макроопределение директива ENDM) (end оf mасrо), Обратите особое внимание на то, что в этой директиве не надо повторять имя макроса (если здесь указать имя макроса, то это предложение будет рассматриватьсякак рекурсивный вызов макроса): Отметим также, что именно эта директива указывается и в конце блоков повторения (в ЯА эти блоки рассматриваются как специфический случай макросов).

Где размещать макроопределения? Они могут быть размешены в любом месте текста программы (по ним в машинную программу ничего не записывается), но обязательно до первой ссылки на этот макрос. Таким образом, в ЯА действует правило: сначала опиши макрос и только затем обращайся к нему.

3.1. Макрокоманды

В тех местах программы, где мы хотим, чтобы макрогенератор подставил макрос, необходимо выписать обращения к макросу в виде макрокоманды, которая записывается следующим образом:

<имя макроса> <фактические параметры через запятую>

Конкретные примеры:

SUM A,ES:B или SUM A ES: B

VAR Z,W,? или VAR Z W,?

Как видно, макрокоманды очень похожи на обычные команды и директивы. Но есть и отличия. Во-первых, вместо названия команды или директивы, являющегося служебным словом, в макрокоманде указывается имя макроса, которое придумал сам автор программы. Во-вторых, в макрокоманде параметры могут отделяться друг от друга как запятыми, так и пробелами. В качестве фактического параметра может быть указан любой текст (в том числе и пустой), но он должен быть сбалансирован по кавычкам и угловым скобкам и в нем не должно быть запятых, пробелов и точек с запятой вне этих кавычек и скобок. Поскольку запятыми и пробелами отделяется один параметр от другого, а с точки с запятой начинается комментарий, то их использование внутри фактического параметра привело бы к путанице. При записи параметров макрокоманд можно использовать те же макро­операторы <>,! и %, что и при записи фактических параметров блоков повторения. Например, если в фактическом параметре надо указать запятую, пробел или точку с запятой, то параметр следует заключить в уголки:

SUM <WORD РТR [SI]>, А VAR С W <1, 2>

При этом, напомним, уголки не считаются относящимися в параметру, а лишь указывают его границы. Число фактических параметров, указываемых в макрокоманде, вообще говоря, должно равняться числу формальных параметров макроса, причем 1-й фактичес­кий параметр соответствует 1-му формальному параметру. Однако, если факти­ческих параметров указано больше, чем надо, то лишние фактические параметры игнорируются, а если меньше, то считается, что в качестве недостающих фактических параметров заданы пустые тексты.



Поделиться:


Последнее изменение этой страницы: 2016-12-13; просмотров: 254; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.117.170.80 (0.013 с.)