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

Автор: Пользователь скрыл имя, 10 Марта 2013 в 15:44, курс лекций

Описание работы

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

Работа содержит 1 файл

Системное программирование 15 лекций.doc

— 946.00 Кб (Скачать)

4

Конкатенация (&)

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

MOVE MACRO TAG REP MOVS&TAG ENDM

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

4

Директивы повторения: 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,<arguments>

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

Ассемблер генерирует блок кода для каждого аргумента. В следующем примере Ассемблер  генерирует 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 

 

 

  

 

4

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

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

Каждая директива 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>

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

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

4

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

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

IFxx [условие] .

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

EXITM .

.

ENDIF

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

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

4

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

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

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

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

EXITM

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

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

 

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

4

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

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

MOVIF MACRO TAG

IFIDN <&TAG>,<B>

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

Обычное использование  амперсанда (&) — для конкатенации, но в данном примере операнд <TAG> без амперсанда не будет работать. В случае, если в макрокоманде не будет указан параметр 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 Условные директивы позволяют контролировать параметры макрокоманд.  

 

 

  

 

 

  

 

 

  

 

 

  

 

 

  

 

 

  

 

Лекция 15. 
Макропроцессоры

4

Основные понятия

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

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

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

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

 

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

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

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

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

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

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

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

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

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

 

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

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

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

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

Информация о работе Системное программирование