Читаем Системное программное обеспечение. Лабораторный практикум полностью

Листинг П3.13. Построение ассемблерного кода по списку триад

unit TrdAsm;

{!!! Зависит от целевой вычислительной системы!!! }

interface

{ Модуль распределения регистров и построения ассемблерного

кода по списку триад }

uses Classes, TrdType, Triads;

const { Префикс наименования временных переменных }

TEMP_VARNAME = _Tmp';

NUM_PROCREG = 6; { Количество доступных регистров }

{ Функция распределения регистров и временных переменных

для хранения промежуточных результатов триад }

function MakeRegisters(listTriad: TTriadList): integer;

{ Функция построения ассемблерного кода по списку триад }

function MakeAsmCode(listTriad: TTriadList;

listCode: TStrings;

flagOpt: Boolean): integer;

implementation

uses SysUtils;

function MakeRegisters(listTriad: TTriadList): integer;

{ Функция распределения регистров и временных переменных

для хранения промежуточных результатов триад.

Результат: количество необходимых временных переменных }

var

i,j,iR,iCnt,iNum: integer;{Счетчики и переменные циклов}

{ Динамический массив для запоминания занятых регистров }

listReg: TList;

begin { Создаем массив для хранения занятых регистров }

listReg:= TList.Create;

Result:= 0;

if listReg <> nil then

try { Обнуляем информационное поле у всех триад }

for i:=listTriad.Count-1 downto 0 do

listTriad[i].Info:= 0;

{ Цикл по всем триадам. Обязательно с конца списка! }

for i:=listTriad.Count-1 downto 0 do

for j:=1 to 2 do { Цикл по всем (2) операндам }

{ Если триада – линейная операция, или «IF»

(первый операнд), или присвоение (второй операнд) }

if ((listTriad[i].TrdType in TriadLineSet)

or (listTriad[i].TrdType = TRD_IF) and (j = 1)

or (listTriad[i].TrdType = TRD_ASSIGN) and (j = 2))

{ и операндом является ссылка на другую триаду }

and (listTriad[i][j].OpType = OP_LINK) then

begin { Запоминаем номер триады, на которую направлена ссылка }

iNum:= listTriad[i][j].TriadNum;

{ Если триаде еще не назначен регистр и если это

не предыдущая триада – надо ей назначить регистр }

if (listTriad[iNum].Info = 0) and (iNum <> i-1) then

begin { Количество назначенных регистров }

iCnt:= listReg.Count-1;

for iR:=0 to iCnt do

begin{ Цикл по массиву назначенных регистров }

{ Если область действия регистра за пределами

текущей триады, то его можно использовать }

if longint(listReg[iR]) >= i then

begin { Запоминаем область действия регистра }

listReg[iR]:= TObject(iNum);

{ Назначаем регистр триаде с номером iNum }

listTriad[iNum].Info:= iR+1;

Break; { Прерываем цикл по массиву регистров }

end;

end; { Если ни один из использованных регистров

не был назначен, надо брать новый регистр }

if listTriad[iNum].Info = 0 then

begin { Добавляем запись в массив регистров,

указываем ей область действия iNum }

listReg.Add(TObject(iNum));

{ Назначаем новый регистр триаде с номером iNum }

listTriad[iNum].Info:= listReg.Count;

end;

end;

end;{ Результат функции: количество записей в массиве

регистров -1, за вычетом числа доступных регистров}

Result:= listReg.Count – (NUM_PROCREG-1);

finally listReg.Free;

end;

end;

function GetRegName(iInfo: integer): string;

{ Функция наименования регистров процессора }

begin

case iInfo of

0: Result:= 'eax';

1: Result:= 'ebx';

2: Result:= 'ecx';

3: Result:= 'edx';

4: Result:= 'esi';

5: Result:= 'edi';

{ Если это не один из регистров – значит,

даем имя временной переменной }

else Result:=

Format(%s%d',[TEMP_VARNAME,iInfo-NUM_PROCREG]);

end{case};

end;

function GetOpName(i: integer; listTriad: TTriadList;

iOp: integer): string;

{ Функция наименования операнда триады

i – номер триады в списке;

listTriad – список триад;

iOp – номер операнда триады }

var iNum: integer; {номенр триады по ссылке}

Triad: TTriad; {текущая триада}

begin

Triad:= listTriad[i]; { Запоминаем текущую триаду }

{ Выборка наименования операнда в зависимости от типа }

case Triad[iOp].OpType of

{ Если константа – значение константы }

OP_CONST: Result:= IntToStr(Triad[iOp].ConstVal);

{ Если переменная – ее имя из таблицы идентификаторов }

OP_VAR:

begin

Result:= Triad[iOp].VarLink.VarName;

{ Если имя совпадает с именем функции,

заменяем его на Result функции }

if Result = NAME_FUNCT then Result:= NAME_RESULT;

end; { Иначе – это регистр }

else { для временного хранения результатов триады }

begin { Запоминаем номер триады }

iNum:= Triad[iOp].TriadNum;

{ Если это предыдущая триада, то операнд не нужен }

if iNum = i-1 then Result:=

else

begin {Берем номер регистра, связанного с триадой}

iNum:= listTriad[iNum].Info;

{ Если регистра нет, то операнд не нужен }

if iNum = 0 then Result:=

{ Иначе имя операнда – это имя регистра }

else Result:= GetRegName(iNum);

end;

end;

end{case};

end;

function MakeMove(const sReg,{имя регистра}

sPrev,{предыдущая команда}

sVal{предыдущая величина в eax}: string;

flagOpt: Boolean{флаг оптимизации}): string;

{ Функция, генерящая код занесения значения в регистр eax }

begin { Если операнд был только что выгружен из eax

или необходимое значение уже есть в аккумуляторе,

нет необходимости записывать его туда снова }

if (Pos(Format(#9'mov'#9 %s,eax',[sReg]), sPrev) = 1)

or (sVal = sReg) then

begin

Result:= ; Exit;

end;

if flagOpt then { Если оптимизация команд включена }

begin

Перейти на страницу:

Похожие книги

Встраиваемые системы. Проектирование приложений на микроконтроллерах семейства 68HC12/HCS12 с применением языка С
Встраиваемые системы. Проектирование приложений на микроконтроллерах семейства 68HC12/HCS12 с применением языка С

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

Дэниэл Дж. Пак , Стивен Ф. Барретт

Программирование, программы, базы данных / Компьютерное «железо» / Программирование / Книги по IT
Секреты приложений Google
Секреты приложений Google

Даже продвинутые пользователи Интернета не подозревают о тех огромных возможностях, которые предоставляют сервисы Google. Автор рассказывает о таких «секретах» сервисов, которые просто немедленно хочется использовать! Создавать сайты и презентации, бродить по улочкам Парижа, изучать звездное небо – все это доступно каждому, кто сидит у экрана монитора и имеет доступ в Интернет. Книга научит вас работать с веб-приложениями и тысячекратно увеличить свои возможности с помощью новейших технологий. Она написана легким, доступным языком и не требует от читателя наличия каких-либо специальных знаний. Книга содержит множество примеров, иллюстраций и будет полезна всем, кто не стоит на месте и стремится сделать свою жизнь более насыщенной и интересной.

Денис Балуев , Денис Игоревич Балуев

Программирование, программы, базы данных / Интернет / Программное обеспечение / Книги по IT