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

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');

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

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

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

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

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

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

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

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

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