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

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

{ Запоминаем имена первого и второго операндов }

sReg1:= GetOpName(i,listTriad,1);

sReg2:= GetOpName(i,listTriad,2);

{ Если имя первого операнда пустое, значит, он уже

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

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

if (sReg1 = ) or (sReg1 = sVal) then

listCode.Add(MakeOpCode(i,listTriad,sOp,sReg2,

sPrev,sVal,flagOpt))

else { Если имя второго операнда пустое, значит он уже

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

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

if (sReg2 = ) or (sReg2 = sVal) then

begin

listCode.Add(MakeOpCode(i,listTriad,sOp,sReg1,

sPrev,sVal,flagOpt));

{ Если есть дополнительная операция, генерируем ее код

(когда операция несимметричная – например "-") }

if sAddOp <> then

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

end

else { Если оба операнда не пустые, то надо:

– сначала загрузить в eax первый операнд;

– сгенерировать код для обработки второго операнда.}

begin

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

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

listCode.Add(MakeOpCode(i,listTriad,sOp,sReg2,

sPrev,sVal,flagOpt));

end;

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

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

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

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

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

TObject(PChar(sReg1)));

end;

end;

procedure MakeCompare(const sOp: string

{флаг операции сравнения});

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

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

begin

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

{ Запоминаем имена первого и второго операндов }

sReg1:= GetOpName(i,listTriad,1);

sReg2:= GetOpName(i,listTriad,2);

{ Если имя первого операнда пустое, значит он уже

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

сравниваем eax со вторым операндом }

if sReg1 = then

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

[sReg2,listTriad[i].MakeString(i)]))

else { Если имя второго операнда пустое, значит он уже

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

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

if sReg2 = then

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

[sReg1,listTriad[i].MakeString(i)]))

else { Если оба операнда не пустые, то надо:

– сначала загрузить в eax первый операнд;

– сравнить eax со вторым операндом. }

begin

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

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

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

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

end; { Загружаем в младший бит eax 1 или 0

в зависимости от флага сравнения }

listCode.Add(Format(#9'set%s'#9'al',[sOp]));

listCode.Add(#9'and'#9'eax,1); {очищаем остальные биты}

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

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

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

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

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

TObject(PChar(sReg1)));

end;

end;

begin { Тело главной функции }

iCnt:= listTriad.Count-1; { Количество триад в списке }

for i:=0 to iCnt do

begin { Цикл по всем триадам от начала списка }

{ Если триада помечена, создаем локальную метку

в списке команд ассемблера }

if listTriad[i].IsLinked then

listCode.Add(Format(@M%d:,[i+1]));

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

case listTriad[i].TrdType of

{ Код для триады IF }

TRD_IF: { Если операнд – константа, }

begin {(это возможно в результате оптимизации)}

if listTriad[i][1].OpType = OP_CONST then

begin { Условный переход превращается

в безусловный, если константа = 0,}

if listTriad[i][1].ConstVal = 0 then

listCode.Add(Format(#9'jmp'#9 @M%d'#9 { %s },

[listTriad[i][2].TriadNum+1,

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

end { а иначе вообще генерировать код не нужно.}

else { Если операнд – не константа }

begin { Берем имя первого операнда }

sR:= GetOpName(i,listTriad,1);

{ Если имя первого операнда пустое,

значит он уже есть в регистре eax

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

if sR = then

{ тогда надо выставить флаг «Z», сравнив eax

с ним самим, но учитывая, что предыдущая

триада для IF – это либо сравнение, либо

логическая операция, это можно опустить}

else { иначе надо сравнить eax с операндом }

listCode.Add(Format(#9'cmp'#9 %s,0,[sR]));

{Переход по условию «NOT Z» на ближайшую метку}

listCode.Add(Format(#9'jnz'#9 @F%d'#9 { %s },

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

{ Переход по прямому условию на дальнюю метку }

listCode.Add(Format(#9'jmp'#9 @M%d',

[listTriad[i][2].TriadNum+1]));

{ Метка для ближнего перехода }

listCode.Add(Format(@F%d:,[i]));

end;

end;

{ Код для бинарных логических операций }

TRD_OR: MakeOper2('or', );

TRD_XOR: MakeOper2('xor', );

TRD_AND: MakeOper2('and', );

{ Код для операции NOT (так как NOT(0)=FFFFFFFF,

то нужна еще операция: AND eax,1 }

TRD_NOT: MakeOper1('not','and',1);

{ Код для операций сравнения по их флагам }

TRD_LT: MakeCompare('l');

TRD_GT: MakeCompare('g');

TRD_EQ: MakeCompare('e');

TRD_NEQ: MakeCompare('ne');

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

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

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

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

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

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

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

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

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