Организация магазина с дисплеем
Рассмотрим теперь организацию магазина с дисплеем. Дисплей - это массив (DISPLAY), i -й элемент которого представляет собой указатель на область активации последней вызванной подпрограммы i -го статического уровня. Доступ к переменным самой внутренней подпрограммы осуществляется через регистр BP. Дисплей может быть реализован либо через регистры (если их достаточно), либо через массив в памяти.
При вызове процедуры следующего (по отношению к вызывающей) уровня в дисплее отводится очередной элемент. Если вызывающая процедура имеет статический уровень i, то при вызове процедуры уровня j <= i элементы дисплея j,...,iдолжны быть скопированы (обычно в стек вызывающей процедуры), текущим уровнем становится j и в DISPLAY[j] заносится указатель на область активации вызываемой процедуры. По окончании работы вызываемой процедуры содержимое дисплея восстанавливается из стека.
Иногда используется комбинированная схема - дисплей в магазине. Дисплей хранится в области активации каждой процедуры. Формирование дисплея для процедуры осуществляется в соответствии с правилами, описанными выше.
Отдельного рассмотрения требует вопрос о технике передачи фактических параметров. Конечно, в случае простых параметров (например, чисел) проблем не возникает. Однако передача массивов по значению - операция довольно дорогая, поэтому с точки зрения экономии памяти целесообразнее сначала в подпрограмму передать адрес массива, а затем уже из подпрограммы по адресу передать в магазин сам массив. В связи с передачей параметров следует упомянуть еще одно обстоятельство.
Рассмотренная схема организации магазина допустима только для языков со статически известными размерами фактических параметров. Однако, например, в языке Модула-2 по значению может быть передан гибкий массив, и в этом случае нельзя статически распределить память для параметров. Обычно в таких случаях заводят так называемый "паспорт" массива, в котором хранится вся необходимая информация, а сам массив размещается в магазине в рабочей области выше сохраненных регистров.
Назначение адресов
Назначение адресов переменным, параметрам и полям записей происходит при обработке соответствующих объявлений. В однопроходном трансляторе это может производиться вместе с построением основной таблицы символов и соответствующие адреса (или смещения) могут храниться в этой же таблице. В промежуточном представлении Лидер объявления сохранены, что делает это промежуточное представление машинно-независимым. Напомним, что в Лидер-представлении каждому описанию соответствует некоторый номер. В процессе работы генератора кодов поддерживается таблица Table, в которой по этому номеру (входу) содержится следующая информация:
· для типа: его размер;
· для переменной: смещение в области процедуры (или глобальной области);
· для поля записи: смещение внутри записи;
· для процедуры: размер локальных параметров;
· для массива: размер массива, размер элемента, значение левой и правой границы.
Для вычисления адресов определим для каждого объявления два синтезируемых атрибута: DISP будет обозначать смещение внутри области процедуры (или единицы компиляции), а SIZE - размер. Тогда семантика правила для списка объявлений принимает вид
RULEDeclPart ::= ( Decl )SEMANTICS Disp<1>=0;1A: Disp<1>=Disp<1>+Size<1>; Size<0>=Disp<1>.Все объявления, кроме объявлений переменных, имеют нулевой размер. Размер объявления переменной определяется следующим правилом:
RULEDecl ::= 'VAR' TypeDesSEMANTICSTablentry Entry;0: Entry=IncTab; Size<0>=((Table[VAL<2>]+1) / 2)*2; // Выравнивание на границу слова Table[Entry]=Disp<0>+Size<0>.В качестве примера трансляции определения типа рассмотрим обработку описания записи:
RULETypeDes ::= 'REC' ( TypeDes ) 'END'SEMANTICSint Disp;Tablentry Temp;0: Entry<0>=IncTab; Disp=0;2A: {Temp=IncTab; Table[Temp]=Disp; Disp=Disp+Table[Entry<2>]+1) / 2)*2; // Выравнивание на границу слова }Table[Entry<0>]=Disp.Дата добавления: 2016-06-13; просмотров: 543;