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

if sReg = 0 then { Если требуемое значение = 0, }

begin{его можно получить из –1 и 1 с помощью INC и DEC}

if sVal = -1 then Result:= #9'inc'#9'eax'

else

if sVal = 1 then Result:= #9'dec'#9'eax'

else Result:= #9'xor'#9'eax,eax'

end {иначе – с помощью XOR}

else

if sReg = 1 then { Если требуемое значение = 1, }

begin{его можно получить из –1 и 0 с помощью NEG и INC}

if sVal = -1 then Result:= #9'neg'#9'eax'

else

if sVal = 0 then Result:= #9'inc'#9'eax'

else

Result:= #9'xor'#9'eax,eax'#13#10#9'inc'#9'eax';

end {иначе – двумя командами: XOR и INC }

else

if sReg = -1 then { Если требуемое значение = -1, }

begin{его можно получить из 1 и 0 с помощью NEG и DEC}

if sVal = 1 then Result:= #9'neg'#9'eax'

else

if sVal = 0 then Result:= #9'dec'#9'eax'

else

Result:= #9'xor'#9'eax,eax'#13#10#9'dec'#9'eax';

end {иначе – двумя командами: XOR и DEC }

{ Иначе заполняем eax командой MOV }

else Result:= Format(#9'mov'#9'eax,%s',[sReg]);

end { Если оптимизация команд выключена,

всегда заполняем eax командой MOV }

else Result:= Format(#9'mov'#9'eax,%s',[sReg]);

end;

function MakeOpcode(i: integer;{номер текущей триады}

listTriad: TTriadList;{список триад}

const sOp,sReg,{код операции и операнд}

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

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

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

{ Функция, генерящая код линейных операций над eax }

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

begin { Запоминаем текущую триаду }

Triad:= listTriad[i];

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

begin

if sReg = 0 then { Если операнд = 0 }

begin

case Triad.TrdType of

TRD_AND: { Для команды AND результат всегда = 0 }

Result:= MakeMove(0 ,sPrev,sVal,flagOpt);

{ Для OR, "+" и «-» ничего не надо делать }

TRD_OR,TRD_ADD,TRD_SUB: Result:= #9#9;

{ Иначе генерируем код выполняемой операции }

else Result:= Format(#9 %s'#9'eax,%s',[sOp,sReg]);

end{case};

end

else

if sReg = 1 then { Если операнд = 1 }

begin

case Triad.TrdType of

TRD_OR: { Для команды OR результат всегда = 1 }

Result:= MakeMove(1 ,sPrev,sVal,flagOpt);

{ Для AND ничего не надо делать }

TRD_AND: Result:= #9#9;

{ Для "+" генерируем операцию INC }

TRD_ADD: Result:= #9'inc'#9'eax';

{ Для «-» генерируем операцию DEC }

TRD_SUB: Result:= #9'dec'#9'eax';

{ Иначе генерируем код выполняемой операции }

else Result:= Format(#9 %s'#9'eax,%s',[sOp,sReg]);

end{case};

end

else

if sReg = -1 then { Если операнд = -1 }

begin

case Triad.TrdType of

{ Для "+" генерируем операцию DEC }

TRD_ADD: Result:= #9'dec'#9'eax';

{ Для «-» генерируем операцию INC }

TRD_SUB: Result:= #9'inc'#9'eax';

{ Иначе генерируем код выполняемой операции }

else Result:= Format(#9 %s'#9'eax,%s',[sOp,sReg]);

end{case};

end { Иначе генерируем код выполняемой операции }

else Result:= Format(#9 %s'#9'eax,%s',[sOp,sReg]);

end { Если оптимизация команд выключена,

всегда генерируем код выполняемой операции }

else Result:= Format(#9 %s'#9'eax,%s',[sOp,sReg]);

{ Добавляем к результату информацию о триаде

в качестве комментария }

Result:= Result + Format(#9 { %s },

[Triad.MakeString(i)]);

end;

function MakeAsmCode(

listTriad: TTriadList;{входной список триад}

listCode: TStrings;{список строк результирующего кода}

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

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

var i,iCnt: integer;{счетчик и переменная цикла}

sR: string;{строка для имени регистра}

sPrev,sVal: string;

{строки для хранения предыдущей команды и значения eax}

procedure TakePrevAsm;

{ Процедура, выделяющая предыдущую команду и значение eax

из списка результирующих команд }

var j: integer;

begin

j:= listCode.Count;

if j > 0 then

begin

sPrev:= listCode[j-1];

sVal:= StrPas(PChar(listCode.Objects[j-1]));

end

else

begin

sPrev:= ; sVal:= ;

end;

end;

procedure MakeOper1(const sOp,{код операции}

sAddOp: string;{код дополнительной операции}

iOp: integer{номер операнда в триаде});

{ Функция генерации кода для унарных операций }

var sReg{строка для имени регистра}: string;

begin

TakePrevAsm; {Берем предыдущую команду и значение из eax}

{ Запоминаем имя операнда }

sReg:= GetOpName(i,listTriad,iOp);

if sReg <> then { Если имя пустое, операнд уже есть в

регистре eax от выполнения предыдущей триады,}

begin { иначе его нужно занести в eax }

{ Вызываем функцию генерации кода занесения операнда }

sReg:= MakeMove(sReg,sPrev,sVal,flagOpt);

if sReg <> then listCode.Add(sReg);

end; { Генерируем непосредственно код операции }

listCode.Add(Format(#9 %s'#9'eax'#9 { %s },

[sOp,listTriad[i].MakeString(i)]));

if sAddOp <> then { Если есть дополнительная операция,

генерируем ее код }

listCode.Add(Format(#9 %s'#9'eax,1,[sAddOp]));

if listTriad[i].Info <> 0 then { Если триада связана с

begin { регистром, запоминаем результат в этом регистре }

sReg:= GetRegName(listTriad[i].Info);

{ При этом запоминаем, что сейчас находится в eax }

listCode.AddObject(Format(#9'mov'#9 %s,eax',[sReg]),

TObject(PChar(sReg)));

end;

end;

procedure MakeOper2(const sOp,{код операции}

sAddOp: string{код дополнительная операции});

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

и логических операций }

var sReg1,sReg2{строки для имен регистров}: string;

begin

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

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

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

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

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

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

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

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

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