Главная страница Случайная страница Разделы сайта АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Трансляция переменных
Переменные отражают все многообразие механизмов доступа в языке. Переменная имеет синтезированный атрибут 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> ]; }.
|