BAULA1 (1110624), страница 20

Файл №1110624 BAULA1 (Лекции Баулы) 20 страницаBAULA1 (1110624) страница 202019-04-28СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 20)

mov ax,8000h; MinInt

irp i,<X>

ifnb <i>

cmpax i

endif

endm

endm

; Вспомогательное макроопределение

cmpax macro X

local L

cmp ax,X

jge L

mov ax,X

L:

endm

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

  • Если фактический параметр заключён в угловые скобки, то они считаются макрооператорами, их обработка заключается в том, что они отбрасываются при передаче фактического параметра на место формального.

  • Символ восклицательного знака (!) является макрооператором, он удаляется из фактического параметра, но при этом блокирует (иногда говорят – экранирует) анализ следующего за ним символа на принадлежность к служебным символам (т.е. макрооператорам). Например, фактический параметр <ab!!+!>> преобразуется в строку ab!+>, именно эта строка и передаётся на место формального параметра. Это один из способов, как можно передать в качестве параметров сами служебные символы.

  • В том случае, если комментарий начинается с двух символов ;; вместо одного, то это макрокомментарий, такой комментарий не переносится в макрорасширение.

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

K=1

irp i,<l,h>

K=K+1

mov a&i,X&K&i

endm

После обработки этого макроцикла Макрокпроцессор подставит на это место в текст программы следующие строки:

mov al,X2l

mov ah,X3h

  • Символ % является макрооператором, он предписывает макропроцессору вычислить следующее за ним арифметическое выражение и подставить значение этого выражения вместо знака %. Например, после обработки предложений

N equ 5

K=1

M equ %(3*K+1)>N

Будут получены предложения

N equ 5

M equ 4>N

Разберём теперь выполнение макроопределения maxn для макрокоманды

maxn <-13,,bx,Z>

На место формального параметра X будет подставлена строка символов -13,,bx,Z. Таким образом, макроцикл принимает следующий вид

irp i,<-13,,bx,Z>

ifnb <i>

cmpax i

endif

endm

В теле этого макроцикла располагается условный макрооператор с именем ifnb, он проверяет свой параметр и вырабатывает значение true, если этот параметр не является пустой строкой символов. Таким образом, получается, что в теле макроцикла выполняется условный макрооператор, который только для непустых элементов из списка цикла вызывает вспомогательное макроопределение cmpax. Единственным назначением этого вспомогательного макроопределения является локализация в нём метки L, которая таким образом получает уникальное значение для каждого параметра из списка цикла.

Упражнение. Напишите макроопределение maxn без использования вспомогательного макроопределения. Надо сразу сказать, что для этого требуется хорошее знание языка Ассемблера.

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

Теперь мы познакомимся с использованием макросредств для настройки макроопределения на типы передаваемых ему фактических параметров. Здесь имеется в виду, что, хотя с точки зрения макропроцессора фактический параметр – это просто строка символов, но с точки зрения Ассемблера у этого параметра может быть тип. Например, в Ассемблере это может быть длинная или короткая целая переменная, константа и т.д. и ясно, что для обработки операндов разных типов требуются и различные команды.

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

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

SumMas macro X,N

В качестве первого параметра этого макроопределения можно задавать массивы коротких или длинных знаковых целых чисел, длина массива указывается во втором параметре. Другими словами, первый операнд макрокоманды SumMas может быть формата m8 или m16, а второй – формата m16 или i16. Сумма должна возвращаться на регистре ax (т.е. наше макроопределение – в некотором смысле функция). Допускается, чтобы второй параметр был опущен, в этом случае по умолчанию считается, что в массиве 100 элементов. Для простоты наше макроопределение не будет сохранять и восстанавливать используемые регистры, а переполнение при сложении будем игнорировать. Кроме того, не будем проверять допустимость типа второго параметра, например, передачу в качестве второго параметра короткого регистра r8 или какой-нибудь метки программы. Ниже показан возможный вариант такого макроопределения.

SumMas macro X,N

Local K,L

ifb <X>

%out Нет массива!

.err

exitm

endif

ifb <N>

%out Берём длину=100

mov cx,100

else

mov cx,N

endif

if type X LT 1 or type X GT 2

%out Плохой тип массива!

.err

exitm

endif

K=word

if type X EQ byte

K=byte

endif

lea bx,X

xor dx,dx; Сумма:=0

if K EQ byte

L: mov al,[bx]

cbw

add dx,ax

else

L: add dx,[bx]

endif

add bx,K

loop L

mov ax,dx

endm

Как видим, наше макроопределение настраивается на тип переданного массива и оставляет в макрорасширении только команды, предназначенные для работы с элементами массива именно этого требуемого типа. Заметьте также, что вся эта работа по настройке на нужный тип параметров производится до начала счёта (на этапе компиляции), то есть на машинном языке получается эффективная программа, не содержащая никаких лишних команд.

Упражнение. Объясните, для чего предназначено показанное ниже макроопределение и как к нему следует обращаться:

BegProc macro R

push bp

mov bp,sp

irp i,<R>

push i

endm

endm

В качестве ещё одного примера рассмотрим следующую задачу. Пусть программисту на Ассемблере необходимо много раз вызывать различные процедуры со стандартным соглашением о связях, передавая им каждый раз досточно большое количество параметров. Естественно, программист хочет автоматизировать процесс вызова процедуры, написав макроопределение, которой позволяет вызывать процедуры почти так же компактно, как и в языках высокого уровня. Например, пусть в Паскале есть описание процедуры с заголовком

Procedure P(var X:Mas; N:integer; var Y:integer);

Такую процедуру можно, например, вызвать оператором процедуры P(X,400,Y) . В Ассемблере для фактических параметров, описанных, например, так:

X dw 400 dup (?)

Y dw ?

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

mov ax,offset X

push ax

mov ax,400

push ax

mov ax,offset Y

push ax

call P

Для автоматизации вызова процедур напишем такое макроопределение:

CallProc macro Name,Param

irp i,<Param>

mov ax,i

push ax

endm

call Name

endm

Вот теперь вызов нашей процедуры можно производить одной макрокомандой

CallProc P,<<offset X>,400,<offset Y>>

Разумеется, это выглядит не так красиво, как в Паскале, но здесь уж ничего не поделаешь, хотя для любителей макрооператоров Ассемблера можно предложить и альтернативный вызов нашего макроопрелеления, не перегруженный угловыми скобками:

CallProc P,<offset! X,400,offset! Y>

Как бы то ни было, главная наша цель достигнута – вызов процедуры стал производиться в одно предложение Ассемблера. Заметим, что пустой список фактических параметров можно, как и в Паскале, полностью опускать, например

CallProc F

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

ifb <Name>

%out Пустое имя процедуры

.err

exitm

endif

Несколько сложнее обстоит дело, если наш программист захочет проверить, что в качестве первого параметра передано именно имя, а не какая-нибудь недопустимая строка символов. Поставленную задачу можно решить, например, с помощью такого фрагмента на Макроассемблере:

Nom=1; Номер символа в имени

irpc i,<Name>

Err=1; Признак ошибки в очередном символе имени

if Nom EQ 1

irpc j,<abcdefghijklmnopqrstuvwxyz

ABCDEFGHIJKLMNOQPRSTUVWXYZ_?@#$>

ifidn <i>,<j>

Err=0

endif

endm

else

irpc j,<abcdefghijklmnopqrstuvwxyz

ABCDEFGHIJKLMNOQPRSTUVWXYZ_?@#$0123456789>

ifidn <i>,<j>

Err=0

endif

endm

endif

if Err EQ 1

exitm; Выход из цикла irpc

endif

endm

if Err EQ 1

%out Плохой символ i в имени Name

.err

exitm; Выход из макроопределения

endif

Для анализа символов фактического параметра на принадлежность заданному множеству символов мы использовали макроцикл irpc. Выполнение этого макроцикла очень похоже на выполнение макроцикла irp, за исключением того, что параметру цикла каждый раз присваивается очередной один символ, входящий в список цикла. В нашем примере в списке цикла мы указали в первом операторе irpc все символы, с которых может начинаться имя в Ассемблере (это латинские буквы и некоторые символы, приравнивающиеся к буквам). Во втором операторе irpc из нашего примера мы к буквам просто добавили 10 цифр. Заметим, что, как уже отмечалось ранее, каждое предложение надо записывать в одну строку, мы разбили каждый из макроциклов irpc на две строки исключительно для удобства чтения нашего примера, что, конечно же, будет классифицировано Ассемблером как синтаксическая ошибка.

Итак, теперь мы убедились, что в качестве первого параметра наше макроопределение получило некоторое имя. Но является ли полученное нами имя именно именем процедуры (или, в более общем случае, именем команды)? Чтобы выяснить это, в наше макроопределение можно вставить проверку типа полученного имени, например, так:

if type Name NE -1 and type Name NE -2

%out Name не имя процедуры!

.err

exitm

endif

Некоторые характеристики имени можно получить также, применив к этому имени одноместный оператор Ассемблера .type. Результатом работы этого оператора является целое значение в формате байта (i8), при этом каждый бит в этом байте, если он установлен в "1", указывает на наличие некоторой характеристики имени. Ниже приведены номера некоторых битов в байте, которое этот оператор вырабатывает, будучи применённым к своему имени-операнду (напомним, что биты в байте нумеруются справа-налево, начиная с нуля):

Так, например, для имени, описанного в Ассемблере как

Характеристики

Тип файла
Документ
Размер
1,27 Mb
Материал
Тип материала
Высшее учебное заведение

Список файлов лекций

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6376
Авторов
на СтудИзбе
309
Средний доход
с одного платного файла
Обучение Подробнее