Главная страница
Навигация по странице:

  • MOVE MACRO TAG REP MOVSTAG ENDM

  • Директивы повторения: REPT, IRP, IRPC

  • IRP: Неопределенное повторение

  • IRPC: Неопределенное повторение символа

  • IF выражение В случае, если выражение не равно нулю, Ассемблер обрабатывает операторы в условном блоке.IFE выражение

  • IF1 (нет выражения) В случае, если осуществляется первый проход ассемблирования то обрабатываются операторы в условном блоке.IF2 (нет выражения)

  • IFDEF идентификатор В случае, если идентификатор определен в программе или объявлен как EXTRN, то Ассемблер обрабатывает операторы в условном блоке.IFNDEF идентификатор

  • IFB В случае, если аргументом является пробел, Ассемблер обрабатывает операторы в условном блоке. Аргумент должен быть в угловых скобках.IFNB

  • Директива выхода из макроса EXITM

  • Макрокоманды, использующие IF и IFNDEF

  • Макрос, использующий IFIDN-условие

  • Важно

  • Макровызов или макрокоманда или макрос

  • Сравнение макросредств и подпрограмм

  • Команды обработки строк лекция. Команды обработки строк. Свойства операций над строками


    Скачать 93.13 Kb.
    НазваниеКоманды обработки строк. Свойства операций над строками
    АнкорКоманды обработки строк лекция.docx
    Дата20.09.2018
    Размер93.13 Kb.
    Формат файлаdocx
    Имя файлаКоманды обработки строк лекция.docx
    ТипДокументы
    #24846
    страница3 из 5
    1   2   3   4   5

    Использование библиотек макроопределений

    Определение таких макрокоманд, как INIT1 и INIT2 и одноразовое их использование в программе кажется бессмысленным. Лучшим подходом здесь является каталогизация собственных макрокоманд в библиотеке на магнитном диске, используя любое описательное имя, например, MACRO.LIB:

    INIT MACRO CSNAME,DSNAME,SSNAME .

    .

    ENDM PROMPT MACRO MESSGE .

    .

    ENDM

    Теперь для использования любой из каталогизированных макрокоманд вместо MACRO определения в начале программы следует применять директиву INCLUDE:

    INCLUDE C:MACRO.LIB .

    .

    INIT CSEG,DATA,STACK

    В этом случае Ассемблер обращается к файлу MACRO.LIB (в нашем примере) на дисководе C и включает в программу оба макроопределения INIT и PROMPT.

    Хотя в нашем примере требуется только INIT. Ассемблерный листинг будет содержать копию макроопределения, отмеченного символом C в 30 колонке LST-файла.

    Следом за макрокомандой идет ее расширение с объектным кодом и с символом плюс (+) в 31 колонке.

    Так как транслятор с Ассемблера является двухпроходовым, то для обеспечения обработки директивы INCLUDE только в первом проходе (а не в обоих) можно использовать следующую конструкцию:

    IF1 INCLUDE C:MACRO.LIB ENDIF

    IF1 и ENDIF являются условными директивами. Директива IF1 указывает Ассемблеру на необходимость доступа к библиотеке только в первом проходе трансляции.

    Директива ENDIF завершает IF-логику. Таким образом, копия макроопределений не появится в листинге — будет сэкономлено и время и память.

    Директива очистки

    Директива INCLUDE указывает Ассемблеру на включение всех макроопределений из специфицированной библиотеки.

    Например, библиотека содержит макросы INIT, PROMPT и DIVIDE, хотя программе требуется только INIT. Директива PURGE позволяет «удалить» нежелательные макросы PROMPT и DIVIDE в текущем ассемблировании:

    IF1 INCLUDE MACRO.LIB ;Включить всю библиотеку

    ENDIF PURGE PROMRT,DIYIDE ;Удалить ненужные макросы ...

    INIT CSEG,DATA,STACK ;Использование оставшейся макрокоманды

     

    Директива PURGE действует только в процессе ассемблирования и не оказывает никакого влияния на макрокоманды, находящиеся в библиотеке.
    Конкатенация (&)

    Символ амперсанд (&) указывает Ассемблеру на сцепление (конкатенацию) текста или символов. Следующая макрокоманда MOVE генерирует команду MOVSB или MOVSW:

    MOVE MACRO TAG REP MOVS&TAG ENDM

    Теперь можно кодировать макрокоманду в виде MOVE B или MOVE W. В результате макрорасширения Ассемблер сцепит параметр с командой MOVS и получит REP MOVSB или REP MOVSW. Данный пример весьма тривиален и служит лишь для иллюстрации.
    Директивы повторения: REPT, IRP, IRPC

    Директивы повторения заставляют Ассемблер повторить блок операторов, завершаемых директивой ENDM.

    Эти директивы не обязательно должны находится в макроопределении, но если они там находятся, то одна директива ENDM требуется для завершения повторяющегося блока, а вторая ENDM — для завершения макроопределения.

    REPT: Повторение

    Операция REPT приводит к повторению блока операторов до директивы ENDM в соответствии с числом повторений, указанным в выражении:

    REPT выражение

     

    В следующем примере происходит начальная инициализация значения N=0 и затем повторяется генерация DB N пять раз:

    N = 0 REPT 5 N = N + 1 DB N ENDM

    В результате будут сгенерированы пять операторов DB от DB 1 до DB 5.

    Директива REPT может использоваться таким образом для определения таблицы или части таблицы. Другим примером может служить генерация пяти команд MOVSB, что эквивалентно REP MOVSB при содержимом CX равном 05:

    REPT 5 MOVSB ENDM

    IRP: Неопределенное повторение

    Операция IRP приводит к повторению блока команд до директивы ENDM.

    Основной формат:

    IRP dummy,

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

    Ассемблер генерирует блок кода для каждого аргумента. В следующем примере Ассемблер генерирует DB 3, DB 9, DB 17, DB 25 и DB 28:

    IRP N,<3, 9, 17, 25, 28> DB N

    ENDM
    IRPC: Неопределенное повторение символа

    Операция IRPC приводит к повторению блока операторов до директивы ENDM. Основной формат:

    IRPC dummy,string

    Ассемблер генерирует блок кода для каждого символа в строке «string». В следующем примере Ассемблер генерирует DW 3, DW 4 ... 
    DW 8:

    IRPC N,345678 DW N

    ENDM

     

    Условные директивы

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

    Каждая директива IF должна иметь спаренную с ней директиву ENDIF для завершения IF-логики и возможную директиву ELSE для альтернативного действия.

    Отсутствие директивы ENDIF вызывает сообщение об ошибке: «Undeterminated conditional» (незавершенный условный блок).

    В случае, если проверяемое условие истинно, то Ассемблер выполняет условный блок до директивы ELSE или при отсутствии ELSE — до директивы ENDIF. В случае, если условие ложно, то Ассемблер выполняет условный блок после директивы ELSE, а при отсутствии ELSE вообще обходит условный блок.

    Ниже перечислены различные условные директивы:

    IF выражение

    В случае, если выражение не равно нулю, Ассемблер обрабатывает операторы в условном блоке.

    IFE выражение

    В случае, если выражение равно нулю, Ассемблер обрабатывает операторы в условном блоке.

    IF1 (нет выражения)

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

    IF2 (нет выражения)

    В случае, если осуществляется второй проход операторы ассемблирования, то обрабатываются в условном блоке.
    IFDEF идентификатор

    В случае, если идентификатор определен в программе или объявлен как EXTRN, то Ассемблер обрабатывает операторы в условном блоке.

    IFNDEF идентификатор

    В случае, если идентификатор не определен в программе или не объявлен как EXTRN, то Ассемблер обрабатывает операторы в условном блоке.

    IFB <аргумент>

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

    IFNB <аргумент>

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

    IFIDN <арг-1>,<арг-2>

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

    IFDIF<арг-1>,<арг-2>

    В случае, если строка первого аргумента отличается от строки второго аргумента, то Ассемблер обрабатывает операторы в условном блоке.

    Аргументы должны быть в угловых скобках.



    Директива выхода из макроса EXITM

    Макроопределение может содержать условные директивы, которые проверяют важные условия. В случае, если условие истинно, то Ассемблер должен прекратить дальнейшее макрорасширение. Для этой цели служит директива EXITM:

    IFxx [условие] .

    . (неправильное условие) .

    EXITM .

    .

    ENDIF

    Как только Ассемблер попадает в процессе генерации макрорасширения на директиву EXITM, дальнейшее расширение прекращается и обработка продолжается после директивы ENDM.

    Можно использовать EXITM для прекращения повторений по директивам REPT, IRP и IRPC даже если они находятся внутри макроопределения.
    Макрокоманды, использующие IF и IFNDEF

    Макроопределение DIVIDE генерирует подпрограмму для выполнения деления вычитанием. Макрокоманда должна кодироваться с параметрами в следующей последовательности: делимое, делитель, частное.

    Макрокоманда содержит директиву IFNDEF для проверки наличия параметров. Для любого неопределенного элемента макрокоманда увеличивает счетчик CNTR. Этот счетчик может иметь любое корректное имя и предназначен для временного использования в макроопределении. После проверки всех трех параметров, макрокоманда проверяет CNTR:

    IF CNTR ;Макрорасширение прекращено

    EXITM

    В случае, если счетчик CNTR содержит ненулевое значение, то Ассемблер генерирует комментарий и прекращает по директиве EXITM дальнейшее макрорасширение. Заметим, что начальная команда устанавливает в счетчике CNTR нулевое значение и, кроме того, блоки IFNDEF могут устанавливать в CNTR единичное значение, а не увеличивать его на 1.

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

     

    Один из способов улучшения рассматриваемой макрокоманды — обеспечить проверку на ненулевой делитель и на одинаковый знак делимого и делителя; для этих целей лучше использовать коды Ассемблера, чем условные директивы.
    Макрос, использующий IFIDN-условие

    Макроопределение по имени MOVIF генерирует команды MOVSB или MOVSW в зависимости от указанного параметра. Макрокоманду можно кодировать с параметром B (для байта) или W (для слова) для генерации команд MOVSB или MOVSW из MOVS. Обратите внимание на первые два оператора в макроопределении:

    MOVIF MACRO TAG

    IFIDN <&TAG>,

    Условная директива IFIDN сравнивает заданный параметр (предположительно B или W) со строкой B. В случае, если значения идентичны, то Ассемблер генерирует REP MOVSB.

    Обычное использование амперсанда (&) — для конкатенации, но в данном примере операнд без амперсанда не будет работать. В случае, если в макрокоманде не будет указан параметр B или W, то Ассемблер сгенерирует предупреждающий комментарий и команду MOVSB (по умолчанию).

    Примеры в кодовом сегменте трижды проверяют макрокоманду MOVIF: для параметра B, для параметра W и для неправильного параметра.

    Не следует делать попыток выполнения данной программы в том виде, как она приведена на рисунке, так как регистры CX и DX не обеспечены правильными значениями.

    Важно:

    u  Макросредства возможны только для полной версии Ассемблера (MASM).

    u  Использование макрокоманд в программах на Ассемблере дает в результате более удобочитаемые программы и более производительный код.

    u  Макроопределение состоит из директивы MACRO, блока из одного или нескольких операторов, которые генерируются при макрорасширениях и директивы ENDM для завершения определения.

    u  Код, который генерируется в программе по макрокоманде, представляет собой макрорасширение.

    u  Директивы .SALL, .LALL и .XALL позволяют управлять распечаткой комментариев и генерируемого объектного кода в макрорасширении.

    u  Директива LOCAL позволяет использовать имена внутри макроопределений. Директива LOCAL кодируется непосредственно после директивы MACRO.

    u  Использование формальных параметров в макроопределении позволяет кодировать параметры, обеспечивающие большую гибкость макросредств.

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

    u  Условные директивы позволяют контролировать параметры макрокоманд.

    Макропроцессоры
    Основные понятия

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

    Определение, которое показанное выше, не представляется удачным, так как оно говорит только о сокращении объема записи, а это лишь одна из возможностей обеспечиваемых Макропроцессором. Хотя Макропроцессоры являются обязательным элементом всех современных языков Ассемблеров, аналогичные модули (Препроцессоры) могут быть и для других языков, в том числе и для языков высокого уровня. Для одних языков (Pascal, PL/1) применение средств препроцессора является опционным, для других (C, C++) — обязательным.

    Важно понимать, что Макропроцессор осуществляет обработку исходного текста. Он «не вникает» в синтаксис и семантику операторов и переменных языка Ассемблера, не знает (как правило) имен, употребляемых в программе, а выполняет только текстовые подстановки. В свою очередь, Ассемблер обрабатывает исходный текст, не зная, написан тот или иной оператор программистом «своей рукой» или сгенерирован Макропроцессором. По тому, насколько Препроцессор (Макропроцессор) и Транслятор (Ассемблер) «знают» о существовании друг друга, их можно разделить на три категории:

    u  Независимые. Препроцессор составляет отдельный программный модуль (независимую программу), выполняющую просмотр (один или несколько) исходного модуля и формирующую новый файл исходного модуля, поступающий на вход Транслятора (пример — язык C).

     

    u  Слабосвязанные. Препроцессор составляет с Транслятором одну программу, но разные секции этой программы. Если в предыдущем случае Препроцессор обрабатывает весь файл, а затем передает его Транслятору, то в этом случае единицей обработки является каждый оператор исходного текста: он обрабатывается секцией Препроцессора, а затем передается секции Транслятора. (Пример — HLASM для S/390).

    u  Сильносвязанные. То же распределение работы, что и в предыдущем случае, но Препроцессор использует некоторые общие с Транслятором структуры данных. Например, Макропроцессор может распознавать имена, определенные в программе директивой EQU и т.п. 
    (Пример — MASM, TASM).

    Основные термины, связанные с данными, обрабатываемыми Макропроцессором:

    u  макровызов (или макрокоманда);

    u  макроопределение;

    u  макрорасширение.

    Макровызов или макрокоманда или макрос — оператор программы, который подлежит обработке Макропроцессором (Макропроцессор обрабатывает не все операторы, а только ему адресованные).

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

    Макрорасширение — результат выполнения макровызова, представляющий собой один или несколько операторов языка Ассемблера, подставляемых в исходный модуль вместо оператора макровызова. Пример обработки макровызова показан на рисунке.

     

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

    Макроопределение описывает, как должна обрабатываться макрокоманда. Средства такого описания составляют некоторый Макроязык. Для Макропроцессоров 1-й и 2-й категорий средства Макроязыка могут быть достаточно развитыми. Для Макропроцессоров 3-й категории средства Макроязыка могут быть довольно бедными, но в составе языка Ассемблера может быть много директив, применяемых в макроопределениях (возможно, — только в макроопределениях). В теле макроопределения могут употребляться операторы двух типов:

    u  операторы Макроязыка, которые не приводят к непосредственной генерации операторов макрорасширения, а только управляют ходом обработки макроопределения;

    u  операторы языка Ассемблера (машинные команды и директивы), которые переходят в макрорасширение, возможно, с выполнением некоторых текстовых подстановок.

    Поскольку макроопределение, обрабатывается перед трансляцией или вместе с ней, макрокоманда, определенная в исходном модуле, может употребляться только в этом исходном модуле и «не видна» из других исходных модулей. Для повторно используемых макроопределений обычно создаются библиотеки макроопределений. В некоторых системах (например, z/OS) макрокоманды обеспечивают системные вызовы и существуют богатейшие библиотеки системных макроопределений.

    Самое очевидное применение макрокоманд — для сокращения записи исходной программы, когда один оператор макровызова заменяется на макрорасширение из двух и более операторов программы. В некоторых случаях макрорасширение может даже содержать и единственный оператор, но просто давать действию, выполняемому этим оператором более понятную мнемонику. Но возможности Макропроцессора гораздо шире. Так, одна и та же макрокоманда с разными параметрами может приводить к генерации совершенно различных макрорасширений — и по объему, и по содержанию.
    Сравнение макросредств и подпрограмм

    Использование макросредств во многом подобно использованию подпрограмм: в обоих случаях мы сокращаем запись исходного текста и создаем повторно используемые фрагменты кода. (Например, в C/C++ вызов псевдофункции неотличим от вызова функции.)

    Принципиальные различия между подпрограммами и макросредствами:

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

    u  Выполнение подпрограммы требует передачи управления с возвратом — команды типа CALL и RET, а команды макрорасширения включаются в общую последовательность команд программы (макровызовы выполняются быстрее).

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

    Общий итог сравнения: макросредства обеспечивают несколько большее быстродействие при несколько больших затратах памяти. Поэтому обычно макросредства применяются для оформления сравнительно небольших фрагментов повторяющегося кода.
    1   2   3   4   5


    написать администратору сайта