263a41cd

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



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

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

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

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

  1. Независимые. Препроцессор составляет отдельный программный модуль (независимую программу), выполняющую просмотр (один или несколько) исходного модуля и формирующую новый файл исходного модуля, поступающий на вход Транслятора (пример - язык C).
  2. Слабосвязанные. Препроцессор составляет с Транслятором одну программу, но разные секции этой программы. Если в предыдущем случае Препроцессор обрабатывает весь файл, а затем передает его Транслятору, то в этом случае единицей обработки является каждый оператор исходного текста: он обрабатывается секцией Препроцессора, а затем передается секции Транслятора. (Пример - HLASM для S/390).
  3. Сильносвязанные. То же распределение работы, что и в предыдущем случае, но Препроцессор использует некоторые общие с Транслятором структуры данных. Например, Макропроцессор может распознавать имена, определенные в программе директивой EQU и т.п. (Пример - MASM, TASM).

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

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

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

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

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

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

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

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

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



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

Определение (ГОСТ)
Загрузчик - программа, которая подготавливает объектную программу к выполнению и инициирует ее выполнение.

Более детально функции Загрузчика следующие:

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

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

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

Функция загрузки сводится к считыванию образа программы с диска (или другого внешнего носителя) в оперативную память.

Функция связывания состоит в компоновки программы из многих объектных модулей. Поскольку каждый из объектных модулей в составе программы был получен в результате отдельного процесса трансляции, который работает только с одним конкретным модулем, обращения к процедурам и данным, расположенным в других модулях, в объектных модулях не содержат актуальных адресов. Загрузчик же "видит" все объектные модули, входящие в состав программы, и он может вставить в обращения к внешним точкам правильные адреса. Загрузчики, которые выполняют функцию связывания вместе с другими функциями, называются Связывающими Загрузчиками. Выполнение функции связывания может быть переложено на отдельную программу, называемую Редактором связей или Компоновщиком. Редактор связей выполняет только функцию связывания - сборки программы из многих объектных модулей и формирование адресов в обращениях к внешним точкам. На выходе Редактора связей мы получаем загрузочный модуль.

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

Существуют программы, которые при написании рассчитываются на размещение в определенных адресах памяти, так называемые, абсолютные программы. Подготовка таких программ к выполнению значительно проще и выполняется она Абсолютным Загрузчиком. Функции такого Загрузчика гораздо проще:

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

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

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

Основные типы Загрузчиков - настраивающие и непосредственно связывающие.



Содержание раздела