В.А. Серебряков - Теория и реализация языков программирования (1114953), страница 30
Текст из файла (страница 30)
Каждый операторcatch описывает диапазон инструкций, для которых он активен, и тип исключения, который он обрабатывает. Кроме того, с оператором связан наборреализующих его инструкций. При возникновении исключительной ситуациипросматривается список операторов catch, чтобы установить соответствие.Исключительная ситуация соответствует оператору catch, если инструкция,вызвавшая исключительную ситуацию, находится в соответствующем диапазоне, а сама исключительная ситуация принадлежит подтипу типа ситуаций, которые обрабатывает оператор catch.
Если соответствующий операторcatch найден, то управление передается обработчику. Если нет — текущий магазинный фрейм удаляется, и исключительная ситуация возбуждаетсявновь.Порядок операторов catch в списке важен. Интерпретатор передает управление первому подходящему оператору catch.8.5. Организация информации в генераторе кодаСинтаксическое дерево в чистом виде несет только информацию о структуре программы. На самом деле в процессе генерации кода требуется такжеинформация о переменных (например, их адреса), процедурах (также адреса,уровни), метках и т.
п. Для представления этой информации возможны различные решения. Наиболее распространены два:– информация хранится в таблицах генератора кода;– информация хранится в соответствующих вершинах дерева.Рассмотрим, например, структуру таблиц, которые могут быть использованы в сочетании с Лидер-представлением. Поскольку Лидер-представлениене содержит информации об адресах переменных, то эту информацию нужноформировать в процессе обработки объявлений и хранить в таблицах. Этокасается и описаний массивов, записей и т. п.
Кроме того, в таблицах такжедолжна содержаться информация о процедурах (адреса, уровни, модули,в которых процедуры описаны, и т. п.).При входе в процедуру в таблице уровней процедур заводится новый вход— указатель на таблицу описаний. При выходе указатель восстанавливаетсяна старое значение. Если промежуточное представление — дерево, то информация может храниться в вершинах самого дерева.160Глава 8. Промежуточное представление программы8.6. Уровень промежуточного представленияКак видно из приведенных примеров, промежуточное представление программы может быть в различной степени близким либо к исходной программе,либо к машине.
Например, промежуточное представление может содержатьадреса переменных, и тогда оно уже не может быть перенесено на другуюмашину. С другой стороны, промежуточное представление может содержатьраздел описаний программы, и тогда информацию об адресах можно извлечьиз обработки описаний. В то же время ясно, что первое более эффективно,чем второе. Операторы управления в промежуточном представлении могутбыть представлены в исходном виде (в виде операторов языка if, for, whileи т.
п.), а могут содержаться в виде переходов. В первом случае некотораяинформация может быть извлечена из самой структуры (например, для оператора for — информация о переменной цикла, которую, может быть, разумнохранить на регистре, для оператора case — информация о таблице метоки т. п.). Во втором случае представление проще и унифицированней.Некоторые формы промежуточного представления удобны для различногорода оптимизаций, некоторые — нет (например, косвенные тройки, в отличиеот префиксной записи, позволяют эффективное перемещение кода).Глава 9ГЕНЕРАЦИЯ КОДАЗадача генератора кода — построение для программы на входном языкеэквивалентной машинной программы.
Обычно в качестве входа для генератора кода служит некоторое промежуточное представление программы.Генерация кода включает ряд специфических независимых подзадач: распределение памяти (в частности, распределение регистров), выбор команд,генерацию объектного (или загрузочного) модуля. Конечно, независимостьэтих подзадач относительна: например, при выборе команд нельзя не учитывать схему распределения памяти, и, наоборот, схема распределения памяти(в частности, регистров) ведет к генерации той или иной последовательностикоманд. Однако удобно и практично эти задачи все же разделять, обращаяпри этом внимание на их взаимодействие.В какой-то мере схема генератора кода зависит от формы промежуточногопредставления. Ясно, что генерация кода из дерева отличается от генерациикода из троек, а генерация кода из префиксной записи отличается от генерации кода из ориентированного графа.
В то же время все генераторыкода имеют много общего, и основные применяемые алгоритмы различаются,как правило, только в деталях, связанных с используемым промежуточнымпредставлением.В дальнейшем в качестве промежуточного представления мы будем использовать префиксную нотацию. А именно, алгоритмы генерации кода будемизлагать в виде атрибутных схем со входным языком Лидер.9.1. Модель машиныПри изложении алгоритмов генерации кода мы будем следовать некотороймодели машины, в основу которой положена система команд микропроцессораMotorola MC68020. В микропроцессоре имеется регистр — счетчик командPC, 8 регистров данных и 8 адресных регистров.В системе команд используются следующие способы адресации:ABS — абсолютная: исполнительным адресом является значение адресноговыражения.IMM — непосредственный операнд: операндом команды является константа, заданная в адресном выражении.6 В.А.
Серебряков162Глава 9. Генерация кодаD — прямая адресация через регистр данных, записывается как Хn, операнд находится в регистре Хn.А — прямая адресация через адресный регистр, записывается как An,операнд находится в регистре An.INDIRECT — записывается как (An), адрес операнда находится в адресномрегистре An.POST — пост-инкрементная адресация, записывается как (Аn)+, исполнительный адрес есть значение адресного регистра An, и после исполнениякоманды значение этого регистра увеличивается на длину операнда.PRE — пре-инкрементная адресация, записывается как -(Аn): перед исполнением операции содержимое адресного регистра An уменьшается на длину операнда, исполнительный адрес равен новому содержимому адресногорегистра.INDISP — косвенная адресация со смещением, записывается как (bd,An),исполнительный адрес вычисляется как (An)+d — содержимое An плюс d.INDEX — косвенная адресация с индексом, записывается как (bd,An, Xn*sc),исполнительный адрес вычисляется как (An)+bd+(Xn)*sc — содержимоеадресного регистра + адресное смещение + содержимое индексного регистра,умноженное на sc.INDIRPC — косвенная через PC (счетчик команд), записывается как (bd,PC), исполнительный адрес определяется выражением (PC)+bd.INDEXPC — косвенная через PC со смещением, записывается как (bd,PC,Xn*sc), исполнительный адрес определяется выражением (PC)+bd+(Xn)*sc.INDPRE — пре-косвенная через память, записывается как ([bd,An,sc*Xn],od) (схема вычисления адресов для этого и трех последующих способов адресацииприведена ниже).INDPOST — пост-косвенная через память: ([bd,An],sc*Xn,od).INDPREPC — пре-косвенная через PC: ([bd,PC,sc*Xn],od).INDPOSTPC — пост-косвенная через PC: ([bd,PC],Xn,od).Здесь bd — это 16- или 32-битная константа, называемая смещением, od— 16- или 32-битная литеральная константа, называемая внешним смещением.
Эти способы адресации могут использоваться в упрощенных формахбез смещений bd и/или od и без регистров An или Xn. Следующие примерыиллюстрируют косвенную постиндексную адресацию:MOVEMOVEMOVEMOVEMOVEMOVED0,D0,D0,D0,D0,D0,([A0])([4,A0])([A0],6)([A0],D3)([A0],D4,12)([$12345678,A0],D4,$FF000000)Индексный регистр Xn может масштабироваться (умножаться) на 2,4, 8, что записывается как sc*Xn. Например, в исполнительном адресе1639.1.
Модель машины([24,A0, 4*D0]) содержимое[A0] + 4 * [D0] + 24.квадратныхскобоквычисляетсякакЭти способы адресации работают следующим образом. Каждый исполнительный адрес содержит пару квадратных скобок [...] внутри пары круглыхскобок, т. е. ([...], ... ). Сначала вычисляется содержимое квадратныхскобок, в результате чего получается 32-битный указатель. Например, еслииспользуется пост-индексная форма [20,A2], то исполнительный адрес —это 20 + [A2]. Аналогично, для преиндексной формы [12,A4,D5] исполнительный адрес — это 12 + [A4] + [D5].Указатель, сформированный содержимым квадратных скобок, используется для доступа в память, чтобы получить новый указатель (отсюда термин«косвенная адресация через память»). К этому новому указателю добавляетсясодержимое внешних круглых скобок, и таким образом формируется исполнительный адрес операнда.В дальнейшем изложении будут использованы следующие команды(в частности, рассматриваются только арифметические команды с целымиоперандами, но не с плавающими):MOVEA ИА, А — загрузить содержимое по исполнительному адресу ИАна адресный регистр А.MOVE ИА1, ИА2 — содержимое по исполнительному адресу ИА1 переписать по исполнительному адресу ИА2.MOVEM список_регистров, ИА — сохранить указанные регистры в памяти, начиная с адреса ИА (регистры указываются маской в самой команде).MOVEM ИА, список_регистров — восстановить указанные регистрыиз памяти, начиная с адреса ИА (регистры указываются маской в самойкоманде).LEA ИА, А — загрузить исполнительный адрес ИА на адресный регистр А.MUL ИА, D — умножить содержимое по исполнительному адресу ИА на содержимое регистра данных D и результат разместить в D (на самом делев системе команд имеются две различные команды MULS и MULU для чиселсо знаком и чисел без знака соответственно; для упрощения мы не будемпринимать во внимание это различие).DIV ИА, D — разделить содержимое регистра данных D на содержимоепо исполнительному адресу ИА и результат разместить в D.ADD ИА, D — сложить содержимое по исполнительному адресу ИА с содержимым регистра данных D и результат разместить в D.SUB ИА, D — вычесть содержимое по исполнительному адресу ИА из содержимого регистра данных D и результат разместить в D.Команды CMP и TST формируют разряды регистра состояний.
Всего имеется 4 разряда: Z — признак нулевого результата, N — признак отрицательногорезультата, V — признак переполнения, C — признак переноса.6*164Глава 9. Генерация кодаCMP ИА, D — из содержимого регистра данных D вычитается содержимоепо исполнительному адресу ИА, при этом формируются все разряды регистрасостояний, но содержимое регистра D не меняется.TST ИА — выработать разряд Z регистра состояний по значению, находящемуся по исполнительному адресу ИА.BNE ИА — условный переход по признаку Z = 1 (не равно) на исполнительный адрес ИА.BEQ ИА — условный переход по признаку Z = 0 (равно) на исполнительный адрес ИА.BLE ИА — условный переход по признаку N or Z (меньше или равно)на исполнительный адрес ИА.BGT ИА — условный переход по признаку not N (больше) на исполнительный адрес ИА.BLT ИА — условный переход по признаку N (меньше) на исполнительныйадрес ИА.BRA ИА — безусловный переход по адресу ИА.JMP ИА — безусловный переход по исполнительному адресу.RTD размер_локальных — возврат из подпрограммы с указанием размералокальных.LINK A, размер_локальных — в магазине сохраняется значение регистраА, в регистр А заносится указатель на это место в магазине, и указательстека продвигается на размер локальных.UNLK A — стек сокращается на размер локальных, и регистр А восстанавливается из магазина.9.2.