Трансляция переменных

Переменные отражают все многообразие механизмов доступа в языке. Переменная имеет синтезированный атрибут ADDRESS - это запись, описывающая адрес в команде МС68020. Этот атрибут сопоставляется всем нетерминалам, представляющим значения. В системе команд МС68020 много способов адресации, и они отражены в структуре значения атрибута ADDRESS, имеющего следующий тип:

enum Register{D0,D1,D2,D3,D4,D5,D6,D7, A0,A1,A2,A3,A4,A5,A6,SP,NO}; enum AddrMode{D,A,Post,Pre,Indirect,IndPre,IndPost,IndirPC,IndPrePC,IndPostPC,InDisp,Index,IndexPC,Abs,Imm}; struct AddrType{ Register AddrReg,IndexReg; int IndexDisp,AddrDisp; short Scale;};

Значение регистра NO означает, что соответствующий регистр в адресации не используется.

Доступ к переменным осуществляется в зависимости от их уровня: глобальные переменные адресуются с помощью абсолютной адресации; переменные в процедуре текущего уровня адресуются через регистр базы А6.

Если стек организован с помощью статической цепочки, то переменные предыдущего статического уровня адресуются через регистрстатической цепочки А5 ; переменные остальных уровней адресуются "пробеганием" по статической цепочке с использованием вспомогательного регистра. Адрес переменной формируется при обработке структуры переменной слева направо и передается сначала сверху вниз как наследуемый атрибут нетерминала VarTail, а затем передается снизу-вверх как глобальный атрибут нетерминала Variable. Таким образом, правило для обращения к переменной имеет вид (первое вхождение Number в правую часть - это уровень переменной, второе - ее Лидер-номер):

RULEVariable ::= VarMode Number Number VarTailSEMANTICSint Temp;struct AddrType AddrTmp1, AddrTmp2;3: if (Val<2>==0) // Глобальная переменная {Address<4>.AddrMode=Abs; Address<4>.AddrDisp=0; } else // Локальная переменная {Address<4>.AddrMode=Index; if (Val<2>==Level<Block>) // Переменная // текущего уровня Address<4>.AddrReg=A6; else if (Val<2>==Level<Block>-1) // Переменная предыдущего уровня Address<4>.AddrReg=A5; else {Address<4>.Addreg= GetFree(RegSet<Block>); AddrTmp1.AddrMode=Indirect; AddrTmp1.AddrReg=A5; Emit2(MOVEA,AddrTmp1, Address<4>.AddrReg); AddrTmp1.AddrReg=Address<4>.AddrReg; AddrTmp2.AddrMode=A; AddrTmp2.AddrReg=Address<4>.AddrReg; for (Temp=Level<Block>-Val<2>; Temp>=2;Temp--) Emit2(MOVEA,AddrTmp1,AddrTmp2); } if (Val<2>==Level<Block>) Address<4>.AddrDisp=Table[Val<3>]; else Address<4>.AddrDisp= Table[Val<3>]+Table[LevelTab[Val<2>]]; }.

Функция GetFree выбирает очередной свободный регистр (либо регистр данных, либо адресный регистр) и отмечает его как использованный в атрибуте RegSet нетерминала Block. Процедура Emit2 генерирует двухадресную команду. Первый параметр этой процедуры - код команды, второй и третий параметры имеют тип AddrType и служат операндами команды. Смещение переменной текущего уровня отсчитывается от базы ( А6 ), а других уровней - от указателя статической цепочки, поэтому оно определяется как алгебраическая сумма размера локальных параметров и величины смещения переменной. Таблица LevelTab - это таблица уровней процедур, содержащая указатели на последовательно вложенные процедуры.

Если стек организован с помощью дисплея, то трансляция для доступа к переменным может быть осуществлена следующим образом:

RULEVariable ::= VarMode Number Number VarTailSEMANTICSint Temp;3: if (Val<2>==0) // Глобальная переменная {Address<4>.AddrMode=Abs; Address<4>.AddrDisp=0; } else // Локальная переменная {Address<4>.AddrMode=Index; if (Val<2>=Level<Block>) // Переменная // текущего уровня {Address<4>.AddrReg=A6; Address<4>.AddrDisp=Table[Val<3>]; } else {Address<4>.AddrMode=IndPost; Address<4>.AddrReg=NO; Address<4>.IndexReg=NO; Address<4>.AddrDisp=Display[Val<2>]; Address<4>.IndexDisp=Table[Val<3>]; } }.

Рассмотрим трансляцию доступа к полям записи. Она описывается следующим правилом ( Number - это Лидер- номер описания поля):

RULEVarTail ::= 'FIL' Number VarTailSEMANTICSif (Address<0>.AddrMode==Abs) {Address<3>.AddrMode=Abs; Address<3>.AddrDisp= Address<0>.AddrDisp+Table[Val<2>]; } else {Address<3>=Address<0>; if (Address<0>.AddrMode==Index) Address<3>.AddrDisp= Address<0>.AddrDisp+Table[Val<2>]; else Address<3>.IndexDisp= Address<0>.IndexDisp+Table[Val<2>]; }.







Дата добавления: 2016-06-13; просмотров: 679;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.004 сек.