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

Листинг П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

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

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

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных