Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
(*
* uAsm.pas - ¬®¤г«м ЇаҐ®Ўа §®ў Ёп ваЁ ¤ ў asm-Є®¤
* ver. 0.37
* 21.05.2007 serg
*)
unit uAsm;
interface
uses uStack, Grams, uTrList, Lex;
procedure triada_to_asm;
procedure print_all_table;
function checkUseTriad: Integer;
procedure tr_begprog;
procedure tr_endprog;
procedure write_AsmProc;
procedure selMemory(countTmpVars: Integer);
procedure tr_defl;
procedure tr_brl;
procedure tr_bf;
procedure tr_RelOp(oper: string);
procedure tr_AddOp(oper: string);
procedure tr_DivOp(oper: string);
procedure tr_mul;
procedure tr_LogOp(oper: string);
procedure tr_not;
procedure tr_neg;
procedure tr_eq;
procedure tr_wrt;
procedure tr_wrts;
procedure tr_wrtm;
procedure tr_rd;
procedure tr_ColRow(oper: string);
procedure tr_subs;
procedure tr_addr;
procedure tr_eqa;
procedure tr_ConDis(oper: string; dest: string);
procedure tr_blbeg;
procedure tr_blend;
implementation
var f_proc:text;
f_body:text;
f_var :text;
gl_curTriadNum: Integer;
gl_curTriada: tTriadData;
labelCount: Integer; (* бзҐвзЁЄ ЈҐҐаЁа㥬ле ¬Ґв®Є *)
function isVariable(s: string): boolean;
begin
isVariable := s[1]='_';
end;
function isConstVariable(s: string): boolean;
begin
isConstVariable := (s[1]='_') and (s[2]='2');
end;
(*=================================================================*)
(*====== Ћб®ў п Їа®жҐ¤га - ЇҐаҐў®¤ Ї®в®Є ваЁ ¤ ў asm-Є®¤ ======*)
procedure triada_to_asm;
var
i:integer;
op: string;
nextTriada: tTriadData;
begin
labelCount := 0;
print_all_table; (* а бЇҐз в Ґ¬ ўбҐ в Ў«Ёжл ў д ©«л *)
assign(f_var,'var.asm');
rewrite(f_var);
assign(f_proc,'proc.asm');
rewrite(f_proc);
assign(f_body,'body.asm');
rewrite(f_body);
tr_begprog;
for gl_curTriadNum := 1 to TriadList.top do begin
getTriadElemNum(TriadList, gl_curTriadNum, gl_curTriada);
op := gl_curTriada.name;
if (op = 'DEFL') then tr_defl
else if (op = 'BRL') then tr_BRL
else if (op = 'BF') then tr_bf
else if (op = 'WRT') then tr_wrt
else if (op = 'WRTS') then tr_wrts
else if (op = 'WRTM') then tr_wrtm
else if (op = 'RD') then tr_rd
else if (op = 'EQ') then tr_eq
else if (op = 'NEG') then tr_neg
else if (op = 'NOT') then tr_not
else if (op = 'OR') then tr_LogOp(op)
else if (op = 'AND') then tr_LogOp(op)
else if (op = 'MUL') then tr_mul
else if (op = 'DIV') then tr_DivOp(op)
else if (op = 'MOD') then tr_DivOp(op)
else if (op = 'ADD') then tr_AddOp(op)
else if (op = 'SUB') then tr_AddOp(op)
else if (op = 'CON')or(op = 'DIS') then
begin
getTriadElemNum(TriadList, gl_curTriadNum+1, nextTriada);
tr_ConDis(op, nextTriada.op1);
end
else if (op = 'LDM') then begin (*NULL*) end
else if (op = 'SUBS') then tr_subs
else if (op = 'ADDR') then tr_addr
else if (op = 'EQA') then tr_eqa
else if (op = 'ROW') then tr_ColRow(op)
else if (op = 'COL') then tr_ColRow(op)
else if (op = 'BLBEG') then tr_blbeg (*#*)
else if (op = 'BLEND') then tr_blend (*#*)
else if (op = '>') then tr_RelOp(op)
else if (op = '<') then tr_RelOp(op)
else if (op = '>=') then tr_RelOp(op)
else if (op = '<=') then tr_RelOp(op)
else if (op = '=') then tr_RelOp(op)
else if (op = '<>') then tr_RelOp(op)
else writeln(f_body, '; Err!! ЌҐ а бЇ®§ ’аЁ ¤ ', gl_curTriada.name);
end;
tr_endprog;
close(f_var);
close(f_proc);
close(f_body);
end;
(*==========================================================================
======== Џа®ўҐаЄ Ё бва®©Є ббл«®Є ваЁ ¤ ¤агЈ ¤агЈ =================
ў®§ўа й Ґв Є®«-ў® ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›• ¤«п еа ҐЁп ўаҐ¬Ґле १г«мв в®ў*)
function checkUseTriad: Integer;
(*--------------------------------------------------------------------------*)
(* Њ ЄбЁ¬ «м®Ґ Є®«ЁзҐбвў® ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›• *)
const maxCountTmpVars = 20;
(* ђҐ «м® Ґ®Ўе®¤Ё¬®Ґ Є®«ЁзҐбвў® ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›• *)
var realCountTmpVars: Integer;
(* ‚६Ґ Євг «м®бвЁ ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›•:
* ¤«п Є ¦¤®© ЇҐаҐ¬Ґ®© ᮤҐа¦Ёв ®¬Ґа и Ј , Є®Ј¤ ҐҐ § 票Ґ бв Ґв Ґг¦л¬, ...
* ...в.Ґ. Є®Ј¤ нв ЇҐаҐ¬Ґ п ¬.Ў. ЁбЇ®«м§®ў ¤«п еа ҐЁп ¤агЈ®Ј® Їа®¬Ґ¦-Ј® १г«мв в *)
var timeTmpVars: array[1..maxCountTmpVars] of Integer;
(*---------------------------------------------------------------------*)
(* ‚뤥«ҐЁҐ бў®Ў®¤®© ‚ђ…Њ…ЌЌЋ‰ Џ…ђ…Њ…ЌЌЋ‰ Ї®¤ १г«мв в ⥪г饩 ...
* ...ваЁ ¤л gl_curTriada б ®¬Ґа®¬ и Ј gl_curTriadNum *)
function getNumTmpVar: Integer;
var freeNum: Integer;
begin
freeNum := 1;
while timeTmpVars[freeNum] >= gl_curTriadNum do inc(freeNum);
(* freeNum == ®¬Ґа ЇҐаў®© ўбваҐзҐ®© Ґ Євг «м®© ‚ђ…Њ…ЌЌЋ‰ Џ…ђ…Њ…ЌЌЋ‰ *)
if freeNum > realCountTmpVars then realCountTmpVars := freeNum;
(* ўаҐ¬п Євг «м®бвЁ i-© ‚ђ…Њ…ЌЌЋ‰ Џ…ђ…Њ…ЌЌЋ‰ == ...
* ...== ўаҐ¬п Євг «м®б⨠१г«мв в ⥪г饩 ваЁ ¤л *)
timeTmpVars[freeNum] := gl_curTriada.useInfo.endUse;
getNumTmpVar := freeNum;
end;
(*-------------------------------------------------------------------*)
(*------- Ё§ў«ҐЄ Ґв Ё§ бва®ЄЁ ‘‘›‹Љ“ (в.Ґ. зЁб«® Ё§ бЄ®Ў®Є): --------
* getTriadLink('(14)') -> 15 // Ґб«Ё Ґбвм ‘‘›‹ЉЂ (зЁб«® ў бЄ®ЎЄ е)
* getTriadLink('lalala') -> 0 // Ґб«Ё ‘‘›‹Љ€ Ґв
*)
function getTriadLink(s: string): Integer;
var i,code,num:integer;
numStr: string;
begin
getTriadLink := 0;
if length(s)=0 then exit;
if s[1]='(' then begin
numStr := '';
i := 2;
while (s[i]<>')') or (i<length(s)) do begin
numStr := numStr + s[i];
inc(i);
end;
Val(numStr, num, code);
if code=0 then getTriadLink := num;
end;
end;(* getTriadLink *)
(*---------------------------------------------------------------------------*)
(* Џ®¬Ґз Ґв ваЁ ¤г б ®¬Ґа®¬ link Є Є ЁбЇ®«м§гҐ¬го Ё ЇҐаҐ бва Ёў Ґв UseInfo *)
procedure setUseTriad(link: Integer);
var linkedTriad: tTriadData;
begin
getTriadElemNum(TriadList, link, linkedTriad); (* „®бв Ґ¬ ваЁ ¤г Ё§ в Ў«Ёжл *)
(* ЏҐаҐ бва®Ё¬ userInfo *)
with linkedTriad.useInfo do begin
isUse := true;
endUse := gl_curTriadNum; (*в.Є. gl_curTriadNum == ®¬Ґа ⥪г饩 ваЁ ¤л, ...
... Є®в®а п Їа®ўҐапҐвбп ў checkUseTriad Ё ббл« Ґвбп ваЁ ¤г б ®¬Ґа®¬ link *)
end;
setTriadElemNum(TriadList, link, linkedTriad); (* ‚бв ўЁ¬ Ё§¬ҐҐго ваЁ ¤г ®Ўа в® ў в Ў«Ёжг *)
end;(* setUseTriad *)
var linkOp1, linkOp2: Integer;
i: Integer;
linkedTriad: tTriadData;
s: string;
begin
(* Џа®е®¤ 1 == Џ®¬ҐвЁ¬ ваЁ ¤л, Є®в®алҐ Ґбвм ббл«ЄЁ б ¤агЈЁе ваЁ ¤ *)
for gl_curTriadNum := 1 to TriadList.top do begin (* Їа®ЎҐЈ Ґ¬ Ї® ўбҐ¬ ваЁ ¤ ¬ *)
getTriadElemNum(TriadList, gl_curTriadNum, gl_curTriada);
(* Џ®б¬®ваЁ¬: Ґбвм «Ё ‘‘›‹ЉЂ б нв®© ваЁ ¤л ¤агЈЁҐ? *)
(* €§ў«ҐЄ Ґ¬ ‘‘›‹Љ€ Ё§ ®ЇҐа ¤®ў *)
linkOp1 := getTriadLink(gl_curTriada.op1);
linkOp2 := getTriadLink(gl_curTriada.op2);
if linkOp1<>0 then setUseTriad(linkOp1); (* Ї®¬Ґз Ґв ваЁ ¤г б ®¬Ґа®¬ linkOp1 Є Є "€бЇ®«м§гҐ¬ п" *)
if linkOp2<>0 then setUseTriad(linkOp2); (* Ї®¬Ґз Ґв ваЁ ¤г б ®¬Ґа®¬ linkOp2 Є Є "€бЇ®«м§гҐ¬ п" *)
end;
(* ЋЎг«ҐЁҐ ўаҐ¬Ґ Євг «м®бвЁ ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›• *)
for i := 1 to maxCountTmpVars do timeTmpVars[i] := 0;
realCountTmpVars := 0; (* Ї®Є ‚ђ…Њ…ЌЌ›… Џ…ђ…Њ…ЌЌ›… Ґ г¦л *)
(* Џа®е®¤ 2 == § ¬ҐЁ¬ ў ваЁ ¤ е ббл«ЄЁ Ё¬Ґ ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›• *)
for gl_curTriadNum := 1 to TriadList.top do begin (* Їа®ЎҐЈ Ґ¬ Ї® ўбҐ¬ ваЁ ¤ ¬ *)
getTriadElemNum(TriadList, gl_curTriadNum, gl_curTriada);
(* …б«Ё и १г«мв в Є®¬г-⮠㦥 *)
if gl_curTriada.useInfo.isUse then
gl_curTriada.useInfo.numTmpVar := getNumTmpVar; (* ўл¤Ґ«Ё¬ ‚ђ…Њ…ЌЌ“ћ Џ…ђ…Њ…ЌЌ“ћ Ї®¤ १г«мв в *)
(* …б«Ё ¬ г¦л змЁ-⮠१г«мв вл*)
linkOp1 := getTriadLink(gl_curTriada.op1);
if linkOp1<>0 then begin
getTriadElemNum(TriadList, linkOp1, linkedTriad);
str(linkedTriad.useInfo.numTmpVar, s);
gl_curTriada.op1 := '_tmp_'+s;
end;
linkOp2 := getTriadLink(gl_curTriada.op2);
if linkOp2<>0 then begin
getTriadElemNum(TriadList, linkOp2, linkedTriad);
str(linkedTriad.useInfo.numTmpVar, s);
gl_curTriada.op2 := '_tmp_'+s;
end;
setTriadElemNum(TriadList, gl_curTriadNum, gl_curTriada); (* ўбв ўЁ¬ Ё§¬ҐҐго ваЁ ¤г ®Ўа в® ў в Ў«Ёжг *)
end;
(* ў®§ўа вЁ¬ Є®«-ў® ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›• ¤«п еа ҐЁп ўаҐ¬Ґле १г«мв в®ў*)
checkUseTriad := realCountTmpVars;
end;(* checkUseTriad *)
(*=================================================================================================*)
(*============== ѓҐҐаЁа®ў ЁҐ asm-Є®¤ з « Їа®Ја ¬¬л ==========================================*)
procedure tr_begprog;
var countTmpVars: Integer;
begin
writeln(f_var, '; ‘⥪ Їа®Ја ¬¬л');
writeln(f_var, 'Stck SEGMENT STACK');
writeln(f_var, ' DW 128 DUP(?) ; Ћвў®¤Ёвбп 128 б«®ў Ї ¬пвЁ');
writeln(f_var, 'Stck ENDS');
writeln(f_var, '; „ лҐ Їа®Ја ¬¬л');
writeln(f_var, 'DATA SEGMENT');
countTmpVars := checkUseTriad; (* Їа®ўҐаЁ¬ Ё бва®Ё¬ ббл«ЄЁ ваЁ ¤ ¤агЈ ¤агЈ *)
(*а бЇаҐ¤Ґ«ҐЁҐ Ї ¬пвЁ*)
selMemory(countTmpVars);
writeln(f_proc, 'DATA ENDS');
writeln(f_proc, '; Љ®¤ Їа®Ја ¬¬л');
writeln(f_proc, 'CODE SEGMENT');
writeln(f_proc, ' ASSUME CS:CODE, DS:DATA, SS:Stck');
write_AsmProc;
writeln(f_proc, '; ѓ®«®ў п Їа®жҐ¤га ');
writeln(f_proc, 'Main PROC FAR');
writeln(f_proc, ' push DS ;‘®еа ҐЁҐ ¤аҐб з « PSP ў б⥪Ґ');
writeln(f_proc, ' sub AX, AX ;¤«п Ї®б«Ґ¤го饣® ў®ббв ®ў«ҐЁп Ї®');
writeln(f_proc, ' push AX ;Є®¬ ¤Ґ ret, § ўҐаи о饩 Їа®жҐ¤гаг.');
writeln(f_proc, ' mov AX, DATA ; ‡ Јаг§Є ᥣ¬Ґв®Ј®');
writeln(f_proc, ' mov DS, AX ; ॣЁбва ¤ ле.');
end;(* tr_begprog *)
(*=================================================================================================*)
(*============== ѓҐҐаЁа®ў ЁҐ asm-Є®¤ Є®ж Їа®Ја ¬¬л ===========================================*)
procedure tr_endprog;
begin
writeln(f_body, ' ret ; ‚л室 ў DOS Ї® Є®¬ ¤Ґ,');
writeln(f_body, ' ; е-бп ў 1-®¬ б«®ўҐ PSP.');
writeln(f_body, 'Main ENDP');
writeln(f_body, 'CODE ENDS');
writeln(f_body, ' END Main');
end;(* tr_endprog *)
(*=================================================================================================*)
(*============== ђ бЇаҐ¤Ґ«ҐЁҐ Ї ¬пвЁ Ї®¤ ЇҐаҐ¬ҐлҐ ==============================================*)
procedure selMemory(countTmpVars: Integer);
var t: tTable;
var i: Integer;
var p: tTable;
var n1,n2,n3, e: Integer;
begin
t := constTable;
writeln(f_var,' ; Љ®бв вл');
writeln(f_var,' b_true equ 1 ; true');
writeln(f_var,' b_false equ 0 ; false');
while t <> nil do begin
with t^ do begin
if col1 = 'INTEGER' then writeln(f_var,' _',num,' equ ', col2, ' ; ', id);
if col1 = 'BOOLEAN' then writeln(f_var,' _',num,' equ b_', col2, ' ; ',col1);
end;
t := t^.next;
end;
t := varTable;
writeln(f_var,' ; ЏҐаҐ¬ҐлҐ');
while t <> nil do begin
with t^ do begin
if col1 = 'INTEGER' then
writeln(f_var,' _',num,' dw 0 ; ', id,': ',col1)
else if col1 = 'BOOLEAN' then
writeln(f_var,' _',num,' dw 0 ; ', id,': ',col1)
end;
t := t^.next;
end;
if countTmpVars > 0 then begin
writeln(f_var,' ; ЏҐаҐ¬ҐлҐ ¤«п еа ҐЁп Їа®¬Ґ¦гв®зле १г«мв в®ў');
for i := 1 to countTmpVars do
writeln(f_var,' _tmp_',i,' dw 0');
end;
if strCount > 0 then begin
writeln(f_var,' ; ‘ва®Є®ўлҐ Є®бв вл');
for i := 1 to strCount do
writeln(f_var, ' _str', i, ' db "',strTable[i],'", 0DH, 0AH, "$"');
end;
t := varTable;
writeln(f_var,' ; Њ ваЁжл');
while t <> nil do begin
if t^.num <> 400 then
with t^ do begin
if (col1 <> 'INTEGER')and(col1 <> 'BOOLEAN') then begin
p := SearchId(typeTable,col1);
(*!!!* if p <> nil then **)
Val(p^.col2,n1,e);
(*!!!* if e = 0 then **)
Val(p^.col3,n2,e);
writeln(f_var,' _',num,' dw ',n1*n2,' dup(0) ; ', id,': ',col1)
end;
end;
t := t^.next;
end;
end;(* selMemory *)
(*=================================================================================================*)
(*============== ‡ ЇЁбм ў asm-д ©« Ґ®Ўе®¤Ё¬ле Їа®жҐ¤га ===========================================*)
procedure write_AsmProc;
procedure write_PrnMsg;
begin
writeln(f_proc,'WriteMsg PROC NEAR');
writeln(f_proc,' push AX');
writeln(f_proc,' mov AH,9');
writeln(f_proc,' int 21h');
writeln(f_proc,' pop AX');
writeln(f_proc,' ret');
writeln(f_proc,'WriteMsg ENDP');
writeln(f_var, ' ; ‚бЇ®¬®Ј ⥫млҐ Є®бв вл');
writeln(f_var, ' EOLN db 0DH, 0AH, "$"', ' ; ЇҐаҐў®¤ бва®ЄЁ');
end; (* write_PrnMsg *)
procedure write_PrnDec;
begin
writeln(f_proc,'PrnDec PROC NEAR');
writeln(f_proc,' push AX');
writeln(f_proc,' push CX');
writeln(f_proc,' push DX');
writeln(f_proc,' push -1');
writeln(f_proc,' mov CX,10');
writeln(f_proc,'pdl1: xor DX,DX');
writeln(f_proc,' div CX');
writeln(f_proc,' push DX');
writeln(f_proc,' or AX,AX');
writeln(f_proc,' jne pdl1');
writeln(f_proc,' mov AH,2h');
writeln(f_proc,'pdl2: pop DX');
writeln(f_proc,' or DX,DX');
writeln(f_proc,' jl pdl3');
writeln(f_proc,' add DL,"0"');
writeln(f_proc,' int 21h');
writeln(f_proc,' jmp pdl2');
writeln(f_proc,'pdl3: pop DX');
writeln(f_proc,' pop CX');
writeln(f_proc,' pop AX');
writeln(f_proc,' ret');
writeln(f_proc,'PrnDec ENDP');
writeln(f_var, ' MINUS db "-","$"', ' ; ¤«п ®ваЁж ⥫мле зЁбҐ«');
end; (* write_PrnDec *)
procedure write_GetDec;
begin
writeln(f_proc,'GetDec PROC NEAR');
writeln(f_proc,' push DI');
writeln(f_proc,' push SI');
writeln(f_proc,' push BP');
writeln(f_proc,' push BX');
writeln(f_proc,' push DX');
writeln(f_proc,' mov DI,0');
writeln(f_proc,' mov SI,0');
writeln(f_proc,' mov BP,10');
writeln(f_proc,' push 1');
writeln(f_proc,' mov AH,08h');
writeln(f_proc,' int 21h');
writeln(f_proc,' cmp AL,"-"');
writeln(f_proc,' jne gdl2');
writeln(f_proc,' mov AH,2h');
writeln(f_proc,' mov DL,"-"');
writeln(f_proc,' int 21h');
writeln(f_proc,' pop BX');
writeln(f_proc,' push -1');
writeln(f_proc,'gdl1: mov AH,08h');
writeln(f_proc,' int 21h');
writeln(f_proc,'gdl2: cmp AL,"0"');
writeln(f_proc,' jb gdl3');
writeln(f_proc,' cmp AL,"9"');
writeln(f_proc,' ja gdl1');
writeln(f_proc,' mov BL,AL');
writeln(f_proc,' mov AX,DI');
writeln(f_proc,' mul BP');
writeln(f_proc,' mov DL,BL');
writeln(f_proc,' sub DL,"0"');
writeln(f_proc,' mov DH,0');
writeln(f_proc,' add DX,AX');
writeln(f_proc,' jc gdl1');
writeln(f_proc,' inc SI');
writeln(f_proc,' mov DI,DX');
writeln(f_proc,' mov DL,BL');
writeln(f_proc,' mov AH,02h');
writeln(f_proc,' int 21h');
writeln(f_proc,' jmp gdl1');
writeln(f_proc,'gdl3: cmp SI,0');
writeln(f_proc,' je gdl1');
writeln(f_proc,' cmp AL,13');
writeln(f_proc,' je gdl4');
writeln(f_proc,' cmp AL,8');
writeln(f_proc,' jne gdl1');
writeln(f_proc,' dec SI');
writeln(f_proc,' mov AX,DI');
writeln(f_proc,' mov DX,0');
writeln(f_proc,' div BP');
writeln(f_proc,' mov DI,AX');
writeln(f_proc,' mov DL,8');
writeln(f_proc,' mov AH,2');
writeln(f_proc,' int 21h');
writeln(f_proc,' mov DL,32');
writeln(f_proc,' int 21h');
writeln(f_proc,' mov DL,8');
writeln(f_proc,' int 21h');
writeln(f_proc,' jmp gdl1');
writeln(f_proc,'gdl4: mov AH,2h');
writeln(f_proc,' mov DL,13');
writeln(f_proc,' int 21h');
writeln(f_proc,' mov DL,10');
writeln(f_proc,' int 21h');
writeln(f_proc,' mov AX,DI');
writeln(f_proc,' pop BX');
writeln(f_proc,' cmp BX,1');
writeln(f_proc,' je gdl5');
writeln(f_proc,' neg AX');
writeln(f_proc,'gdl5: pop DX');
writeln(f_proc,' pop BX');
writeln(f_proc,' pop BP');
writeln(f_proc,' pop SI');
writeln(f_proc,' pop DI');
writeln(f_proc,' ret');
writeln(f_proc,'GetDec ENDP');
end; (* write_GetDec *)
procedure write_PrnMatr;
begin
writeln(f_proc,';*******');
writeln(f_proc,'; ‚лў®¤ ¬ ббЁў нЄа ў ўЁ¤Ґ ¬ ваЁжл ');
writeln(f_proc,'; BX - ¤аҐб ¬ ббЁў ');
writeln(f_proc,'; CX - Є®«ЁзҐбвў® бва®Є');
writeln(f_proc,'; ‚X - Є®«ЁзҐбвў® бв®«Ўж®ў');
writeln(f_proc,'PrnMatr PROC NEAR');
writeln(f_proc,' push DX');
writeln(f_proc,' mov DX, 0');
writeln(f_proc,' mov AH, 2h ');
writeln(f_proc,'pml1:');
writeln(f_proc,' push CX');
writeln(f_proc,' mov BP, SP');
writeln(f_proc,' mov CX, [BP+2]');
writeln(f_proc,' mov DI, 0');
writeln(f_proc,'pml2:');
writeln(f_proc,' push DX');
writeln(f_proc,' mov SI, DX');
writeln(f_proc,' add SI, DI');
writeln(f_proc,' add SI, DI');
writeln(f_proc,' mov DX, [BX][SI]');
writeln(f_proc,' add DX, "0"');
writeln(f_proc,' int 21h');
writeln(f_proc,' pop DX');
writeln(f_proc,' inc DI');
writeln(f_proc,' loop pml2');
writeln(f_proc,' push DX');
writeln(f_proc,' mov DX, 0Dh');
writeln(f_proc,' int 21h');
writeln(f_proc,' mov DX, 0Ah');
writeln(f_proc,' int 21h');
writeln(f_proc,' pop DX');
writeln(f_proc,' mov BP, SP');
writeln(f_proc,' mov CX, [BP+2]');
writeln(f_proc,' add DX, CX');
writeln(f_proc,' add DX, CX');
writeln(f_proc,' pop CX');
writeln(f_proc,' loop pml1');
writeln(f_proc,' pop AX');
writeln(f_proc,' ret');
writeln(f_proc,'PrnMatr ENDP');
end; (* write_PrnMatr *)
procedure write_ConDisMatr;
begin
writeln(f_proc,';*******');
writeln(f_proc,'; CON & DIS (Љ®коЄжЁп Ё „Ё§коЄжЁп ¬ ббЁў®ў)');
writeln(f_proc,'; DI - ¤аҐб ЇаЁҐ¬ЁЄ ');
writeln(f_proc,'; SI - ¤аҐб Ёбв®зЁЄ 1');
writeln(f_proc,'; BX - ¤аҐб Ёбв®зЁЄ 2');
writeln(f_proc,'; CX - Є®«ЁзҐбвў® п祥Є');
writeln(f_proc,'; DX - вЁЇ ®ЇҐа жЁЁ (1 - DIS, 0 - CON)');
writeln(f_proc,'ConDisMatr PROC NEAR');
writeln(f_proc,' mov AX, DS ; бва®©Є ES DS');
writeln(f_proc,' mov ES, AX');
writeln(f_proc,'cml:');
writeln(f_proc,' lodsw ; ЇҐаҐбл«Є ®зҐаҐ¤®Ј® б«®ў ў AX Ё§ Ёбв®зЁЄ 1');
writeln(f_proc,'');
writeln(f_proc,' or DX, DX ; ®ЇаҐ¤Ґ«Ё¬ вЁЇ ®ЇҐа жЁЁ Ё ўлЇ®«Ё¬ ҐҐ');
writeln(f_proc,' je cml_CON');
writeln(f_proc,' or AX, [BX] ; DIS');
writeln(f_proc,' jmp cml_DIS');
writeln(f_proc,'cml_CON:');
writeln(f_proc,' and AX, [BX] ; CON');
writeln(f_proc,'cml_DIS:');
writeln(f_proc,'');
writeln(f_proc,' and AX, 01h ; ўл¤Ґ«пҐ¬ Ґ¤ЁбвўҐл© г¦л© ЇҐаўл© ЎЁв');
writeln(f_proc,' stosw ; १г«мв в - Є« ¤Ґ¬ ў ЇаЁҐ¬ЁЄ');
writeln(f_proc,' add BX, 2 ; б¤ўЁЈ Є б«Ґ¤го饩 п祩ЄҐ Ёбв®зЁЄ 2');
writeln(f_proc,' loop cml ; жЁЄ«, Ї®Є Ґ Їа®и«Ё ўбҐ п祩ЄЁ');
writeln(f_proc,' ret');
writeln(f_proc,'ConDisMatr ENDP');
end; (* write_ConDisMatr *)
var fl_write_PrnDec: Boolean; (* == Ўл«л «Ё § ЇЁб ў asm-Є®¤ asm-дгЄжЁп PrnDec *)
var fl_write_PrnMsg: Boolean; (* == Ўл«л «Ё § ЇЁб ў asm-Є®¤ asm-дгЄжЁп PrnMsg *)
var fl_write_PrnMatr: Boolean;(* == Ўл«л «Ё § ЇЁб ў asm-Є®¤ asm-дгЄжЁп PrnMatr*)
var fl_write_GetDec: Boolean; (* == Ўл«л «Ё § ЇЁб ў asm-Є®¤ asm-дгЄжЁп GetDec *)
var fl_write_ConDisMatr: Boolean; (* == Ўл«л «Ё § ЇЁб ў asm-Є®¤ asm-дгЄжЁп ConDisMatr *)
op: String;
begin
fl_write_PrnDec := false;
fl_write_PrnMsg := false;
fl_write_PrnMatr:= false;
fl_write_GetDec := false;
fl_write_ConDisMatr := false;
for gl_curTriadNum := 1 to TriadList.top do begin
getTriadElemNum(TriadList, gl_curTriadNum, gl_curTriada);
op := gl_curTriada.name;
if (op = 'WRT') then begin
if not fl_write_PrnMsg then begin
write_PrnMsg;
fl_write_PrnMsg:= true;
end;
if not fl_write_PrnDec then begin
write_PrnDec;
fl_write_PrnDec:= true;
end;
end
else if (op = 'WRTS') then begin
if not fl_write_PrnMsg then begin
write_PrnMsg;
fl_write_PrnMsg:= true;
end;
end
else if (op = 'WRTM') then begin
if not fl_write_PrnMatr then begin
write_PrnMatr;
fl_write_PrnMatr:= true;
end;
end
else if (op = 'CON')or(op = 'DIS') then begin
if not fl_write_ConDisMatr then begin
write_ConDisMatr;
fl_write_ConDisMatr:= true;
end;
end
else if (op = 'RD') then begin
if not fl_write_GetDec then begin
write_GetDec;
fl_write_GetDec:= true;
end;
end
end;
end;
(*=== DEFL - ®ЇаҐ¤Ґ«ҐЁҐ ¬ҐвЄЁ ====================================================================*)
procedure tr_defl;
begin
writeln(f_body, ' ; (', gl_curTriada.name, ', ', gl_curTriada.op1, ')');
writeln(f_body, ' lab', gl_curTriada.op1, ':');
end;
(*=== BRL - ЎҐ§гб«®ўл© ЇҐаҐе®¤ ¬ҐвЄг ==========================================================*)
procedure tr_brl;
begin
writeln(f_body, ' ; (', gl_curTriada.name, ', ', gl_curTriada.op1, ')');
writeln(f_body, ' jmp lab', gl_curTriada.op1);
end;
(*=== BF - гб«®ўл© ЇҐаҐе®¤ ¬ҐвЄг ==============================================================*)
procedure tr_bf;
var op1,op2: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* if op1 then goto op2 *)
if (op1='true') or (op1='false') then op1:='b_'+op1;
writeln(f_body, ' mov AX, ',op1);
writeln(f_body, ' cmp AX, 0');
(* ђ миҐ Ўл«® в Є:
* writeln(f_body, ' je ', op2);
* Ћ¤ Є® Ґб«Ё ¬ҐвЄ op2 ¤ «миҐ +/- 128, в® ЇҐаҐ©вЁ ҐҐ ®ЇҐа в®а®¬ гб«®ў®Ј® ЇҐаҐе®¤ Ґў®§¬®¦®.
* Џ®н⮬г ⥯Ґам ¬ҐвЄг op2 ЇҐаҐе®¤Ё¬ б Ї®¬®ймо jmp
*)
writeln(f_body, ' jne _l',labelCount);
writeln(f_body, ' jmp lab', op2);
writeln(f_body,' _l',labelCount,':');
inc(labelCount);
if (gl_curTriada.useInfo.isUse) then
(* ! ! ! Error - Ї®ЇлвЄ б®еа Ёвм १г«мв в ®ЇҐа жЁЁ BF ў® ўаҐ¬Ґго ЇҐаҐ¬Ґго *)
writeln(f_body, ' ; ! ! ! Error - Ї®ЇлвЄ б®еа Ёвм १г«мв в '+
'®ЇҐа жЁЁ BF ў® ўаҐ¬Ґго ЇҐаҐ¬Ґго ', op2);
end;
(*=== EQA - ЇаЁбў Ёў ЁҐ Ї® ¤аҐбг ================================================================*)
procedure tr_eqa;
var op1,op2: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* [op2] := op1, Ј¤Ґ op2 - ¤аҐб п祩ЄЁ*)
if (op1='true') or (op1='false') then op1:='b_'+op1;
writeln(f_body, ' mov BX, ', op2);
writeln(f_body, ' mov AX, ', op1);
writeln(f_body, ' mov [BX], AX');
(* end; *)
if (gl_curTriada.useInfo.isUse) then
(* ! ! ! Error - Ї®ЇлвЄ б®еа Ёвм १г«мв в ®ЇҐа жЁЁ ЇаЁбў Ёў Ёп ў® ўаҐ¬Ґго ЇҐаҐ¬Ґго *)
writeln(f_body, ' ; ! ! ! Error - Ї®ЇлвЄ б®еа Ёвм १г«мв в '+
'®ЇҐа жЁЁ ЇаЁбў Ёў Ёп ў® ўаҐ¬Ґго ЇҐаҐ¬Ґго ', op2);
(* writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX'); *)
end;
(*=== EQ - ЇаЁбў Ёў ЁҐ ===========================================================================*)
procedure tr_eq;
var op1,op2: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* op2 := op1 *)
if not isVariable(op2) then begin
(* ! ! ! Error - ў ®ЇҐа в®аҐ ЇаЁбў Ёў ЁЁ б«Ґў - ЌҐЏҐаҐ¬Ґ п *)
writeln(f_body, ' ; ! ! ! Error - ў ®ЇҐа в®аҐ ЇаЁбў Ёў ЁЁ б«Ґў - ЌҐЏҐаҐ¬Ґ п ', op2);
exit;
end;
(* §¤Ґбм isVariable(op2) *)
if isConstVariable(op2) then begin
(* ! ! ! Warning - ў ®ЇҐа в®аҐ ЇаЁбў Ёў ЁЁ б«Ґў - Љ®бв в п ЏҐаҐ¬Ґ п *)
writeln(f_body, ' ; ! ! ! Warning - ў ®ЇҐа в®аҐ ЇаЁбў Ёў ЁЁ б«Ґў - Љ®бв в п ЏҐаҐ¬Ґ п', op2);
exit;
end;
if (op1='true') or (op1='false') then op1:='b_'+op1;
(* FixMe 08.05.2007 serg*)
(* гв®зЁвм ЇаЁаЁбў®ҐЁп вЁЇ <k:=1> - ¬.Ў. ¬®¦® <mov _402, 1> *)
(* if isVariable(op1) then begin *)
writeln(f_body, ' mov AX, ', op1);
writeln(f_body, ' mov ', op2 ,', AX');
(* end; *)
if (gl_curTriada.useInfo.isUse) then
(* ! ! ! Error - Ї®ЇлвЄ б®еа Ёвм १г«мв в ®ЇҐа жЁЁ ЇаЁбў Ёў Ёп ў® ўаҐ¬Ґго ЇҐаҐ¬Ґго *)
writeln(f_body, ' ; ! ! ! Error - Ї®ЇлвЄ б®еа Ёвм १г«мв в '+
'®ЇҐа жЁЁ ЇаЁбў Ёў Ёп ў® ўаҐ¬Ґго ЇҐаҐ¬Ґго ', op2);
(* writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX'); *)
end;
(*=== WRT - ўлў®¤ § 票п нЄа ===============================================================*)
procedure tr_wrt;
var op1: string;
begin
op1 := gl_curTriada.op1;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ')');
(* FixMe ¤®ЇЁб вм ¤«п <WRT, true> *)
if (op1='true') or (op1='false') then op1:='b_'+op1;
writeln(f_body,' mov AX, ', op1);
writeln(f_body,' cmp AX, 0');
writeln(f_body,' jge _l', labelCount);
writeln(f_body,' neg AX');
writeln(f_body,' mov DX, OFFSET MINUS');
writeln(f_body,' call WriteMsg');
writeln(f_body,' _l',labelCount,': call PrnDec');
writeln(f_body,' mov DX, OFFSET EOLN');
writeln(f_body,' call WriteMsg');
inc(labelCount);
end;
(*=== WRTM - ўлў®¤ ¬ ваЁжл нЄа ===============================================================*)
procedure tr_wrtm;
var op1: string;
var t: tTable;
var i: Integer;
var p: tTable;
var rowCount,colCount,resultNum, op2Num, e: Integer;
var typeName, resultStr, matrNumberStr: string;
var matrNumber: Integer;
begin
op1 := gl_curTriada.op1;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ')');
(* WRTM op1 *)
(*Find variable ==> type ==> bounds*)
p := varTable;
matrNumberStr := Copy(op1,2,3);
Val(matrNumberStr,matrNumber,e);
while p <> nil do begin
if p^.num = matrNumber then begin
break
end;
p := p^.next
end;
if (p=nil) then begin
writeln(f_body, ' ; Matrix not found in varTable');
exit;
end;
typeName := p^.col1;
p := SearchId(typeTable,typeName);
if (p=nil) then begin
writeln(f_body, ' ; Type of Matrix not found in TypeTable');
exit;
end;
(*!!!* if e = 0 then **)
Val(p^.col2, colCount,e);
Val(p^.col3, rowCount,e);
writeln(f_body,' mov BX, OFFSET ',op1);
writeln(f_body,' mov CX, ',p^.col2,'; col count');
writeln(f_body,' mov DX, ',p^.col3,'; row count');
writeln(f_body,' call PrnMatr');
end;
(*=== WRTS - ўлў®¤ бва®ЄЁ нЄа ===============================================================*)
procedure tr_wrts;
var op1: string;
begin
op1 := gl_curTriada.op1;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ')');
writeln(f_body,' mov DX, OFFSET _str',op1);
writeln(f_body,' call WriteMsg');
end;
(*=================================================================================================*)
procedure tr_rd;
var op1,op2: string;
begin
op1 := gl_curTriada.op1;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ')');
writeln(f_body, ' call GetDec');
writeln(f_body, ' mov ', op1,', AX');
end;
(*=================================================================================================*)
procedure tr_neg;
var op1,op2: string;
begin
op1 := gl_curTriada.op1;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ')');
(* - op1*)
writeln(f_body, ' mov AX, ', op1);
writeln(f_body, ' neg AX');
if (gl_curTriada.useInfo.isUse) then
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
(*=================================================================================================*)
procedure tr_not;
var op1: string;
begin
op1 := gl_curTriada.op1;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ')');
(* not op1*)
if (op1='true') or (op1='false') then op1:='b_'+op1;
writeln(f_body, ' mov AX, ', op1);
writeln(f_body, ' not AX');
writeln(f_body, ' and AX, 01h');
if (gl_curTriada.useInfo.isUse) then
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
(*=== AddOp in [ADD, SUB] - ®ЇҐа жЁЁ ‘«®¦ҐЁҐ Ё ‚лзЁв ЁҐ =========================================*)
procedure tr_AddOp(oper: string);
var op1,op2: string;
labelNum1, labelNum2: Integer;
operStr: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* op2 @ op1, Ј¤Ґ @ in [+, -] *)
if (oper = 'ADD') then operStr := 'add'
else if (oper = 'SUB') then operStr := 'sub'
else operStr := '!!! Err';
labelNum1 := labelCount; inc(labelCount);
labelNum2 := labelCount; inc(labelCount);
writeln(f_body, ' mov AX, ', op2);
writeln(f_body, ' ',operStr,' AX, ', op1);
if (gl_curTriada.useInfo.isUse) then
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
(*=== LogOp in [AND, OR] - «®ЈЁзҐбЄЁҐ ®ЇҐа жЁЁ €, €‹€ =============================================*)
procedure tr_LogOp(oper: string);
var op1,op2: string;
labelNum1, labelNum2: Integer;
operStr: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* op2 @ op1, Ј¤Ґ @ in [or, and] *)
if (op1='true') or (op1='false') then op1:='b_'+op1;
if (op2='true') or (op2='false') then op2:='b_'+op2;
if (oper = 'AND') then operStr := 'je '
else if (oper = 'OR') then operStr := 'jne'
else operStr := '!!! Err';
labelNum1 := labelCount; inc(labelCount);
labelNum2 := labelCount; inc(labelCount);
writeln(f_body, ' mov AX, ', op2);
writeln(f_body, ' cmp AX, 0');
writeln(f_body, ' ',operStr ,' _l', labelNum1);
writeln(f_body, ' mov AX, ', op1);
writeln(f_body, ' cmp AX, 0');
writeln(f_body, ' ',operStr ,' _l', labelNum1);
if (oper = 'AND') then
writeln(f_body, ' mov AX, 1 ; true')
else if (oper = 'OR') then
writeln(f_body, ' mov AX, 0 ; false');
writeln(f_body, ' jmp _l', labelNum2);
writeln(f_body,' _l',labelNum1,':');
if (oper = 'AND') then
writeln(f_body, ' mov AX, 0 ; false')
else if (oper = 'OR') then
writeln(f_body, ' mov AX, 1 ; true');
writeln(f_body,' _l',labelNum2,':');
if (gl_curTriada.useInfo.isUse) then
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
(*=== RelOp - «®ЈЁзҐбЄЁҐ ®ЇҐа жЁЁ ба ўҐЁп =======================================================*)
procedure tr_RelOp(oper: string);
var op1,op2: string;
labelNum1, labelNum2: Integer;
operStr: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* op2 @ op1, Ј¤Ґ @ in [>, <, >=, <=, =, <>] *)
if (oper = '>') then operStr := 'jg '
else if (oper = '<') then operStr := 'jl '
else if (oper = '>=') then operStr := 'jge'
else if (oper = '<=') then operStr := 'jle'
else if (oper = '=') then operStr := 'je '
else if (oper = '<>') then operStr := 'jne'
else operStr := '!!! Err';
labelNum1 := labelCount; inc(labelCount);
labelNum2 := labelCount; inc(labelCount);
writeln(f_body, ' mov AX, ', op2);
writeln(f_body, ' cmp AX, ', op1);
writeln(f_body, ' ',operStr ,' _l', labelNum1);
writeln(f_body, ' mov AX, 0 ; false');
writeln(f_body, ' jmp _l', labelNum2);
writeln(f_body,' _l',labelNum1,':');
writeln(f_body, ' mov AX, 1 ; true');
writeln(f_body,' _l',labelNum2,':');
if (gl_curTriada.useInfo.isUse) then
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
(*=================================================================================================*)
procedure tr_mul;
var op1,op2: string;
operand1: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* op2 * op1*)
writeln(f_body, ' mov AX, ', op2);
if isVariable(op1) and not isConstVariable(op1) then begin
operand1 := op1; (* - в Є ¬®¦® в®«мЄ® ¤«п Ќ бв®пйЁе ЇҐаҐ¬Ґле (~ _401) *)
end else begin
writeln(f_body, ' mov BX, ', op1);
operand1 := 'BX';(* - Є®бв вл Ё Є®бв влҐ ЇҐаҐ¬ҐлҐ - зҐаҐ§ ॣЁбва *)
end;
writeln(f_body, ' imul ', operand1);
(* ђҐ§г«мв в ў DX:AX, ® ЎҐаҐ¬ в®«мЄ® ¬« ¤иго з бвм - Ё§ AX *)
if (gl_curTriada.useInfo.isUse) then
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
(*=================================================================================================*)
procedure tr_DivOp(oper: string);
var op1,op2: string;
operand1: string;
resultStr: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* op2 @ op1, Ј¤Ґ @ in [div, mod] *)
writeln(f_body, ' mov AX, ', op2, ' ; б«®ў®-¤Ґ«Ё¬®Ґ - ў AX');
writeln(f_body, ' cwd ; а биЁаЁвм ¤Ґ«Ё¬®Ґ ў DX' );
if isVariable(op1) and not isConstVariable(op1) then begin
operand1 := op1; (* - в Є ¬®¦® в®«мЄ® ¤«п Ќ бв®пйЁе ЇҐаҐ¬Ґле (~ _401) *)
end else begin
writeln(f_body, ' mov BX, ', op1, ' ; б«®ў®-¤Ґ«ЁвҐ«м - ў BX');
operand1 := 'BX'; (* - Є®бв вл Ё Є®бв влҐ ЇҐаҐ¬ҐлҐ - зҐаҐ§ ॣЁбва *)
end;
writeln(f_body, ' idiv ', operand1,' ; ®бв в®Є:з б⮥ ў DX:AX');
if (gl_curTriada.useInfo.isUse) then begin
if (oper = 'DIV') then resultStr := 'AX'
else if (oper = 'MOD') then resultStr := 'DX';
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', ',resultStr);
end;
end;
(*=================================================================================================*)
procedure tr_ConDis(oper: string; dest: string);
var op1,op2: string;
var t: tTable;
var i: Integer;
var p: tTable;
var rowCount,colCount, e: Integer;
var typeName, matrNumberStr: string;
var matrNumber: Integer;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* dest := op1 @ op2, @ in [DIS, CON]*)
(*Find variable ==> type ==> bounds*)
p := varTable;
matrNumberStr := Copy(op1,2,3);
Val(matrNumberStr,matrNumber,e);
while p <> nil do begin
if p^.num = matrNumber then begin
break
end;
p := p^.next
end;
if (p=nil) then begin
writeln(f_body, ' ; Matrix not found in varTable');
exit;
end;
typeName := p^.col1;
p := SearchId(typeTable,typeName);
if (p=nil) then begin
writeln(f_body, ' ; Type of Matrix not found in TypeTable');
exit;
end;
(*!!!* if e = 0 then **)
Val(p^.col2, colCount,e);
Val(p^.col3, rowCount,e);
writeln(f_body, ' mov DI, OFFSET ', dest,' ; ЇаЁҐ¬ЁЄ');
writeln(f_body, ' mov SI, OFFSET ', op1, ' ; Ёбв®зЁЄ1');
writeln(f_body, ' mov BX, OFFSET ', op2, ' ; Ёбв®зЁЄ2');
writeln(f_body, ' mov CX, ',colCount*rowCount, ' ; зЁб«® п祥Є');
if (oper = 'CON') then
writeln(f_body, ' mov DX, 0 ; вЁЇ ®ЇҐа жЁЁ - CON')
else
writeln(f_body, ' mov DX, 1 ; вЁЇ ®ЇҐа жЁЁ - DIS');
writeln(f_body, ' call ConDisMatr');
end;
(*=================================================================================================*)
procedure tr_subs;
var op1,op2: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* SUBS op1 op2 == op1[op2] - ᮤҐа¦Ё¬®Ґ п祩ЄЁ*)
writeln(f_body, ' mov BX, ', op2);
writeln(f_body, ' add BX, ', op2); (* в.Ґ. BX*2, в.Є. б«®ў®, Ґ Ў ©в*)
writeln(f_body, ' mov AX, ',op1,'[BX]');
if (gl_curTriada.useInfo.isUse) then begin
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
end;
(*=================================================================================================*)
procedure tr_addr;
var op1,op2: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* SUBS op1 op2 == addr(op1[op2]) - ¤аҐб п祩ЄЁ*)
writeln(f_body, ' mov AX, offset ', op1);
writeln(f_body, ' add AX, ', op2);
writeln(f_body, ' add AX, ', op2); (* в.Ґ. AX*2, в.Є. б«®ў®, Ґ Ў ©в*)
if (gl_curTriada.useInfo.isUse) then begin
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
end;
(*=================================================================================================*)
procedure tr_ColRow(oper: string);
var op1,op2: string;
var t: tTable;
var i: Integer;
var p: tTable;
var rowLength,resultNum, op2Num, e: Integer;
var typeName, matrNumberStr: string;
var matrNumber: Integer;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* @ op1 op2 , Ј¤Ґ @ in [COL, ROW] *)
if (gl_curTriada.useInfo.isUse) then begin
if (oper = 'COL') then begin
writeln(f_body, ' mov AX, ', op2);
writeln(f_body, ' dec AX'); (* (k)-© бв®«ЎҐж => ᬥ饨Ґ (k-1) *)
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end else if (oper = 'ROW') then begin
(*Find variable ==> type ==> bounds*)
p := varTable;
matrNumberStr := Copy(op1,2,3);
Val(matrNumberStr,matrNumber,e);
while p <> nil do begin
if p^.num = matrNumber then begin
break
end;
p := p^.next
end;
if (p=nil) then begin
writeln(f_body, ' ; Matrix not found in varTable');
exit;
end;
typeName := p^.col1;
p := SearchId(typeTable,typeName);
if (p=nil) then begin
writeln(f_body, ' ; Type of Matrix not found in TypeTable');
exit;
end;
(*!!!* if e = 0 then **)
Val(p^.col3, rowLength,e);
resultNum := (op2Num-1)*rowLength;
writeln(f_body, ' mov AX, ', op2);
writeln(f_body, ' dec AX'); (* (k)-п бва®Є => ᬥ饨Ґ (k-1)*rowLength *)
writeln(f_body, ' mov BX, ', rowLength);
writeln(f_body, ' imul BX');
(* ђҐ§г«мв в ў DX:AX, ® ЎҐаҐ¬ в®«мЄ® ¬« ¤иго з бвм - Ё§ AX *)
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
end;
end;
(*=================================================================================================*)
(* ‡ Ј«гиЄ *)
procedure tr_col;
var op1,op2: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; ‡ Ј«гиЄ : (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
end;
(*=================================================================================================*)
(* ‡ Ј«гиЄ *)
procedure tr_blbeg;
begin
writeln(f_body, ' ; ‡ Ј«гиЄ : (', gl_curTriada.name, ')');
end;
(*=================================================================================================*)
(* ‡ Ј«гиЄ *)
procedure tr_blend;
begin
writeln(f_body, ' ; ‡ Ј«гиЄ : (', gl_curTriada.name,')');
end;
(*=================================================================================================*)
procedure print_all_table;
var f: Text;
i: integer;
const fname = 'tables.txt';
procedure print_table(table: tTable);
var t: tTable;
begin
t := table;
writeln(f, 'num':10, 'id':10, 'col1':10, 'col2':10, 'col3':10, 'col4':10);
while t <> nil do begin
with t^ do writeln(f, num:10, id:10, col1:10, col2:10, col3:10, col4:10);
t := t^.next;
end;
end;(*print_table*)
begin
assign(f, fname);
rewrite(f);
writeln(f,'typeTable');
print_table(typeTable);
writeln(f,'constTable');
print_table(constTable);
writeln(f,'varTable');
print_table(varTable);
writeln(f,'labelTable');
print_table(labelTable);
(*
writeln(f,'matrTable');
print_table(matrTable);
writeln(f,'hTable');
print_table(hTable);
*)
writeln(f,'strTable');
writeln(f,'num':10,'str':10);
for i := 1 to strCount do writeln(f, i:10,' <',strTable[i],'>');
close(f);
end;(*print_all_table*)
(*=================================================================================================*)
end .
* uAsm.pas - ¬®¤г«м ЇаҐ®Ўа §®ў Ёп ваЁ ¤ ў asm-Є®¤
* ver. 0.37
* 21.05.2007 serg
*)
unit uAsm;
interface
uses uStack, Grams, uTrList, Lex;
procedure triada_to_asm;
procedure print_all_table;
function checkUseTriad: Integer;
procedure tr_begprog;
procedure tr_endprog;
procedure write_AsmProc;
procedure selMemory(countTmpVars: Integer);
procedure tr_defl;
procedure tr_brl;
procedure tr_bf;
procedure tr_RelOp(oper: string);
procedure tr_AddOp(oper: string);
procedure tr_DivOp(oper: string);
procedure tr_mul;
procedure tr_LogOp(oper: string);
procedure tr_not;
procedure tr_neg;
procedure tr_eq;
procedure tr_wrt;
procedure tr_wrts;
procedure tr_wrtm;
procedure tr_rd;
procedure tr_ColRow(oper: string);
procedure tr_subs;
procedure tr_addr;
procedure tr_eqa;
procedure tr_ConDis(oper: string; dest: string);
procedure tr_blbeg;
procedure tr_blend;
implementation
var f_proc:text;
f_body:text;
f_var :text;
gl_curTriadNum: Integer;
gl_curTriada: tTriadData;
labelCount: Integer; (* бзҐвзЁЄ ЈҐҐаЁа㥬ле ¬Ґв®Є *)
function isVariable(s: string): boolean;
begin
isVariable := s[1]='_';
end;
function isConstVariable(s: string): boolean;
begin
isConstVariable := (s[1]='_') and (s[2]='2');
end;
(*=================================================================*)
(*====== Ћб®ў п Їа®жҐ¤га - ЇҐаҐў®¤ Ї®в®Є ваЁ ¤ ў asm-Є®¤ ======*)
procedure triada_to_asm;
var
i:integer;
op: string;
nextTriada: tTriadData;
begin
labelCount := 0;
print_all_table; (* а бЇҐз в Ґ¬ ўбҐ в Ў«Ёжл ў д ©«л *)
assign(f_var,'var.asm');
rewrite(f_var);
assign(f_proc,'proc.asm');
rewrite(f_proc);
assign(f_body,'body.asm');
rewrite(f_body);
tr_begprog;
for gl_curTriadNum := 1 to TriadList.top do begin
getTriadElemNum(TriadList, gl_curTriadNum, gl_curTriada);
op := gl_curTriada.name;
if (op = 'DEFL') then tr_defl
else if (op = 'BRL') then tr_BRL
else if (op = 'BF') then tr_bf
else if (op = 'WRT') then tr_wrt
else if (op = 'WRTS') then tr_wrts
else if (op = 'WRTM') then tr_wrtm
else if (op = 'RD') then tr_rd
else if (op = 'EQ') then tr_eq
else if (op = 'NEG') then tr_neg
else if (op = 'NOT') then tr_not
else if (op = 'OR') then tr_LogOp(op)
else if (op = 'AND') then tr_LogOp(op)
else if (op = 'MUL') then tr_mul
else if (op = 'DIV') then tr_DivOp(op)
else if (op = 'MOD') then tr_DivOp(op)
else if (op = 'ADD') then tr_AddOp(op)
else if (op = 'SUB') then tr_AddOp(op)
else if (op = 'CON')or(op = 'DIS') then
begin
getTriadElemNum(TriadList, gl_curTriadNum+1, nextTriada);
tr_ConDis(op, nextTriada.op1);
end
else if (op = 'LDM') then begin (*NULL*) end
else if (op = 'SUBS') then tr_subs
else if (op = 'ADDR') then tr_addr
else if (op = 'EQA') then tr_eqa
else if (op = 'ROW') then tr_ColRow(op)
else if (op = 'COL') then tr_ColRow(op)
else if (op = 'BLBEG') then tr_blbeg (*#*)
else if (op = 'BLEND') then tr_blend (*#*)
else if (op = '>') then tr_RelOp(op)
else if (op = '<') then tr_RelOp(op)
else if (op = '>=') then tr_RelOp(op)
else if (op = '<=') then tr_RelOp(op)
else if (op = '=') then tr_RelOp(op)
else if (op = '<>') then tr_RelOp(op)
else writeln(f_body, '; Err!! ЌҐ а бЇ®§ ’аЁ ¤ ', gl_curTriada.name);
end;
tr_endprog;
close(f_var);
close(f_proc);
close(f_body);
end;
(*==========================================================================
======== Џа®ўҐаЄ Ё бва®©Є ббл«®Є ваЁ ¤ ¤агЈ ¤агЈ =================
ў®§ўа й Ґв Є®«-ў® ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›• ¤«п еа ҐЁп ўаҐ¬Ґле १г«мв в®ў*)
function checkUseTriad: Integer;
(*--------------------------------------------------------------------------*)
(* Њ ЄбЁ¬ «м®Ґ Є®«ЁзҐбвў® ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›• *)
const maxCountTmpVars = 20;
(* ђҐ «м® Ґ®Ўе®¤Ё¬®Ґ Є®«ЁзҐбвў® ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›• *)
var realCountTmpVars: Integer;
(* ‚६Ґ Євг «м®бвЁ ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›•:
* ¤«п Є ¦¤®© ЇҐаҐ¬Ґ®© ᮤҐа¦Ёв ®¬Ґа и Ј , Є®Ј¤ ҐҐ § 票Ґ бв Ґв Ґг¦л¬, ...
* ...в.Ґ. Є®Ј¤ нв ЇҐаҐ¬Ґ п ¬.Ў. ЁбЇ®«м§®ў ¤«п еа ҐЁп ¤агЈ®Ј® Їа®¬Ґ¦-Ј® १г«мв в *)
var timeTmpVars: array[1..maxCountTmpVars] of Integer;
(*---------------------------------------------------------------------*)
(* ‚뤥«ҐЁҐ бў®Ў®¤®© ‚ђ…Њ…ЌЌЋ‰ Џ…ђ…Њ…ЌЌЋ‰ Ї®¤ १г«мв в ⥪г饩 ...
* ...ваЁ ¤л gl_curTriada б ®¬Ґа®¬ и Ј gl_curTriadNum *)
function getNumTmpVar: Integer;
var freeNum: Integer;
begin
freeNum := 1;
while timeTmpVars[freeNum] >= gl_curTriadNum do inc(freeNum);
(* freeNum == ®¬Ґа ЇҐаў®© ўбваҐзҐ®© Ґ Євг «м®© ‚ђ…Њ…ЌЌЋ‰ Џ…ђ…Њ…ЌЌЋ‰ *)
if freeNum > realCountTmpVars then realCountTmpVars := freeNum;
(* ўаҐ¬п Євг «м®бвЁ i-© ‚ђ…Њ…ЌЌЋ‰ Џ…ђ…Њ…ЌЌЋ‰ == ...
* ...== ўаҐ¬п Євг «м®б⨠१г«мв в ⥪г饩 ваЁ ¤л *)
timeTmpVars[freeNum] := gl_curTriada.useInfo.endUse;
getNumTmpVar := freeNum;
end;
(*-------------------------------------------------------------------*)
(*------- Ё§ў«ҐЄ Ґв Ё§ бва®ЄЁ ‘‘›‹Љ“ (в.Ґ. зЁб«® Ё§ бЄ®Ў®Є): --------
* getTriadLink('(14)') -> 15 // Ґб«Ё Ґбвм ‘‘›‹ЉЂ (зЁб«® ў бЄ®ЎЄ е)
* getTriadLink('lalala') -> 0 // Ґб«Ё ‘‘›‹Љ€ Ґв
*)
function getTriadLink(s: string): Integer;
var i,code,num:integer;
numStr: string;
begin
getTriadLink := 0;
if length(s)=0 then exit;
if s[1]='(' then begin
numStr := '';
i := 2;
while (s[i]<>')') or (i<length(s)) do begin
numStr := numStr + s[i];
inc(i);
end;
Val(numStr, num, code);
if code=0 then getTriadLink := num;
end;
end;(* getTriadLink *)
(*---------------------------------------------------------------------------*)
(* Џ®¬Ґз Ґв ваЁ ¤г б ®¬Ґа®¬ link Є Є ЁбЇ®«м§гҐ¬го Ё ЇҐаҐ бва Ёў Ґв UseInfo *)
procedure setUseTriad(link: Integer);
var linkedTriad: tTriadData;
begin
getTriadElemNum(TriadList, link, linkedTriad); (* „®бв Ґ¬ ваЁ ¤г Ё§ в Ў«Ёжл *)
(* ЏҐаҐ бва®Ё¬ userInfo *)
with linkedTriad.useInfo do begin
isUse := true;
endUse := gl_curTriadNum; (*в.Є. gl_curTriadNum == ®¬Ґа ⥪г饩 ваЁ ¤л, ...
... Є®в®а п Їа®ўҐапҐвбп ў checkUseTriad Ё ббл« Ґвбп ваЁ ¤г б ®¬Ґа®¬ link *)
end;
setTriadElemNum(TriadList, link, linkedTriad); (* ‚бв ўЁ¬ Ё§¬ҐҐго ваЁ ¤г ®Ўа в® ў в Ў«Ёжг *)
end;(* setUseTriad *)
var linkOp1, linkOp2: Integer;
i: Integer;
linkedTriad: tTriadData;
s: string;
begin
(* Џа®е®¤ 1 == Џ®¬ҐвЁ¬ ваЁ ¤л, Є®в®алҐ Ґбвм ббл«ЄЁ б ¤агЈЁе ваЁ ¤ *)
for gl_curTriadNum := 1 to TriadList.top do begin (* Їа®ЎҐЈ Ґ¬ Ї® ўбҐ¬ ваЁ ¤ ¬ *)
getTriadElemNum(TriadList, gl_curTriadNum, gl_curTriada);
(* Џ®б¬®ваЁ¬: Ґбвм «Ё ‘‘›‹ЉЂ б нв®© ваЁ ¤л ¤агЈЁҐ? *)
(* €§ў«ҐЄ Ґ¬ ‘‘›‹Љ€ Ё§ ®ЇҐа ¤®ў *)
linkOp1 := getTriadLink(gl_curTriada.op1);
linkOp2 := getTriadLink(gl_curTriada.op2);
if linkOp1<>0 then setUseTriad(linkOp1); (* Ї®¬Ґз Ґв ваЁ ¤г б ®¬Ґа®¬ linkOp1 Є Є "€бЇ®«м§гҐ¬ п" *)
if linkOp2<>0 then setUseTriad(linkOp2); (* Ї®¬Ґз Ґв ваЁ ¤г б ®¬Ґа®¬ linkOp2 Є Є "€бЇ®«м§гҐ¬ п" *)
end;
(* ЋЎг«ҐЁҐ ўаҐ¬Ґ Євг «м®бвЁ ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›• *)
for i := 1 to maxCountTmpVars do timeTmpVars[i] := 0;
realCountTmpVars := 0; (* Ї®Є ‚ђ…Њ…ЌЌ›… Џ…ђ…Њ…ЌЌ›… Ґ г¦л *)
(* Џа®е®¤ 2 == § ¬ҐЁ¬ ў ваЁ ¤ е ббл«ЄЁ Ё¬Ґ ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›• *)
for gl_curTriadNum := 1 to TriadList.top do begin (* Їа®ЎҐЈ Ґ¬ Ї® ўбҐ¬ ваЁ ¤ ¬ *)
getTriadElemNum(TriadList, gl_curTriadNum, gl_curTriada);
(* …б«Ё и १г«мв в Є®¬г-⮠㦥 *)
if gl_curTriada.useInfo.isUse then
gl_curTriada.useInfo.numTmpVar := getNumTmpVar; (* ўл¤Ґ«Ё¬ ‚ђ…Њ…ЌЌ“ћ Џ…ђ…Њ…ЌЌ“ћ Ї®¤ १г«мв в *)
(* …б«Ё ¬ г¦л змЁ-⮠१г«мв вл*)
linkOp1 := getTriadLink(gl_curTriada.op1);
if linkOp1<>0 then begin
getTriadElemNum(TriadList, linkOp1, linkedTriad);
str(linkedTriad.useInfo.numTmpVar, s);
gl_curTriada.op1 := '_tmp_'+s;
end;
linkOp2 := getTriadLink(gl_curTriada.op2);
if linkOp2<>0 then begin
getTriadElemNum(TriadList, linkOp2, linkedTriad);
str(linkedTriad.useInfo.numTmpVar, s);
gl_curTriada.op2 := '_tmp_'+s;
end;
setTriadElemNum(TriadList, gl_curTriadNum, gl_curTriada); (* ўбв ўЁ¬ Ё§¬ҐҐго ваЁ ¤г ®Ўа в® ў в Ў«Ёжг *)
end;
(* ў®§ўа вЁ¬ Є®«-ў® ‚ђ…Њ…ЌЌ›• Џ…ђ…Њ…ЌЌ›• ¤«п еа ҐЁп ўаҐ¬Ґле १г«мв в®ў*)
checkUseTriad := realCountTmpVars;
end;(* checkUseTriad *)
(*=================================================================================================*)
(*============== ѓҐҐаЁа®ў ЁҐ asm-Є®¤ з « Їа®Ја ¬¬л ==========================================*)
procedure tr_begprog;
var countTmpVars: Integer;
begin
writeln(f_var, '; ‘⥪ Їа®Ја ¬¬л');
writeln(f_var, 'Stck SEGMENT STACK');
writeln(f_var, ' DW 128 DUP(?) ; Ћвў®¤Ёвбп 128 б«®ў Ї ¬пвЁ');
writeln(f_var, 'Stck ENDS');
writeln(f_var, '; „ лҐ Їа®Ја ¬¬л');
writeln(f_var, 'DATA SEGMENT');
countTmpVars := checkUseTriad; (* Їа®ўҐаЁ¬ Ё бва®Ё¬ ббл«ЄЁ ваЁ ¤ ¤агЈ ¤агЈ *)
(*а бЇаҐ¤Ґ«ҐЁҐ Ї ¬пвЁ*)
selMemory(countTmpVars);
writeln(f_proc, 'DATA ENDS');
writeln(f_proc, '; Љ®¤ Їа®Ја ¬¬л');
writeln(f_proc, 'CODE SEGMENT');
writeln(f_proc, ' ASSUME CS:CODE, DS:DATA, SS:Stck');
write_AsmProc;
writeln(f_proc, '; ѓ®«®ў п Їа®жҐ¤га ');
writeln(f_proc, 'Main PROC FAR');
writeln(f_proc, ' push DS ;‘®еа ҐЁҐ ¤аҐб з « PSP ў б⥪Ґ');
writeln(f_proc, ' sub AX, AX ;¤«п Ї®б«Ґ¤го饣® ў®ббв ®ў«ҐЁп Ї®');
writeln(f_proc, ' push AX ;Є®¬ ¤Ґ ret, § ўҐаи о饩 Їа®жҐ¤гаг.');
writeln(f_proc, ' mov AX, DATA ; ‡ Јаг§Є ᥣ¬Ґв®Ј®');
writeln(f_proc, ' mov DS, AX ; ॣЁбва ¤ ле.');
end;(* tr_begprog *)
(*=================================================================================================*)
(*============== ѓҐҐаЁа®ў ЁҐ asm-Є®¤ Є®ж Їа®Ја ¬¬л ===========================================*)
procedure tr_endprog;
begin
writeln(f_body, ' ret ; ‚л室 ў DOS Ї® Є®¬ ¤Ґ,');
writeln(f_body, ' ; е-бп ў 1-®¬ б«®ўҐ PSP.');
writeln(f_body, 'Main ENDP');
writeln(f_body, 'CODE ENDS');
writeln(f_body, ' END Main');
end;(* tr_endprog *)
(*=================================================================================================*)
(*============== ђ бЇаҐ¤Ґ«ҐЁҐ Ї ¬пвЁ Ї®¤ ЇҐаҐ¬ҐлҐ ==============================================*)
procedure selMemory(countTmpVars: Integer);
var t: tTable;
var i: Integer;
var p: tTable;
var n1,n2,n3, e: Integer;
begin
t := constTable;
writeln(f_var,' ; Љ®бв вл');
writeln(f_var,' b_true equ 1 ; true');
writeln(f_var,' b_false equ 0 ; false');
while t <> nil do begin
with t^ do begin
if col1 = 'INTEGER' then writeln(f_var,' _',num,' equ ', col2, ' ; ', id);
if col1 = 'BOOLEAN' then writeln(f_var,' _',num,' equ b_', col2, ' ; ',col1);
end;
t := t^.next;
end;
t := varTable;
writeln(f_var,' ; ЏҐаҐ¬ҐлҐ');
while t <> nil do begin
with t^ do begin
if col1 = 'INTEGER' then
writeln(f_var,' _',num,' dw 0 ; ', id,': ',col1)
else if col1 = 'BOOLEAN' then
writeln(f_var,' _',num,' dw 0 ; ', id,': ',col1)
end;
t := t^.next;
end;
if countTmpVars > 0 then begin
writeln(f_var,' ; ЏҐаҐ¬ҐлҐ ¤«п еа ҐЁп Їа®¬Ґ¦гв®зле १г«мв в®ў');
for i := 1 to countTmpVars do
writeln(f_var,' _tmp_',i,' dw 0');
end;
if strCount > 0 then begin
writeln(f_var,' ; ‘ва®Є®ўлҐ Є®бв вл');
for i := 1 to strCount do
writeln(f_var, ' _str', i, ' db "',strTable[i],'", 0DH, 0AH, "$"');
end;
t := varTable;
writeln(f_var,' ; Њ ваЁжл');
while t <> nil do begin
if t^.num <> 400 then
with t^ do begin
if (col1 <> 'INTEGER')and(col1 <> 'BOOLEAN') then begin
p := SearchId(typeTable,col1);
(*!!!* if p <> nil then **)
Val(p^.col2,n1,e);
(*!!!* if e = 0 then **)
Val(p^.col3,n2,e);
writeln(f_var,' _',num,' dw ',n1*n2,' dup(0) ; ', id,': ',col1)
end;
end;
t := t^.next;
end;
end;(* selMemory *)
(*=================================================================================================*)
(*============== ‡ ЇЁбм ў asm-д ©« Ґ®Ўе®¤Ё¬ле Їа®жҐ¤га ===========================================*)
procedure write_AsmProc;
procedure write_PrnMsg;
begin
writeln(f_proc,'WriteMsg PROC NEAR');
writeln(f_proc,' push AX');
writeln(f_proc,' mov AH,9');
writeln(f_proc,' int 21h');
writeln(f_proc,' pop AX');
writeln(f_proc,' ret');
writeln(f_proc,'WriteMsg ENDP');
writeln(f_var, ' ; ‚бЇ®¬®Ј ⥫млҐ Є®бв вл');
writeln(f_var, ' EOLN db 0DH, 0AH, "$"', ' ; ЇҐаҐў®¤ бва®ЄЁ');
end; (* write_PrnMsg *)
procedure write_PrnDec;
begin
writeln(f_proc,'PrnDec PROC NEAR');
writeln(f_proc,' push AX');
writeln(f_proc,' push CX');
writeln(f_proc,' push DX');
writeln(f_proc,' push -1');
writeln(f_proc,' mov CX,10');
writeln(f_proc,'pdl1: xor DX,DX');
writeln(f_proc,' div CX');
writeln(f_proc,' push DX');
writeln(f_proc,' or AX,AX');
writeln(f_proc,' jne pdl1');
writeln(f_proc,' mov AH,2h');
writeln(f_proc,'pdl2: pop DX');
writeln(f_proc,' or DX,DX');
writeln(f_proc,' jl pdl3');
writeln(f_proc,' add DL,"0"');
writeln(f_proc,' int 21h');
writeln(f_proc,' jmp pdl2');
writeln(f_proc,'pdl3: pop DX');
writeln(f_proc,' pop CX');
writeln(f_proc,' pop AX');
writeln(f_proc,' ret');
writeln(f_proc,'PrnDec ENDP');
writeln(f_var, ' MINUS db "-","$"', ' ; ¤«п ®ваЁж ⥫мле зЁбҐ«');
end; (* write_PrnDec *)
procedure write_GetDec;
begin
writeln(f_proc,'GetDec PROC NEAR');
writeln(f_proc,' push DI');
writeln(f_proc,' push SI');
writeln(f_proc,' push BP');
writeln(f_proc,' push BX');
writeln(f_proc,' push DX');
writeln(f_proc,' mov DI,0');
writeln(f_proc,' mov SI,0');
writeln(f_proc,' mov BP,10');
writeln(f_proc,' push 1');
writeln(f_proc,' mov AH,08h');
writeln(f_proc,' int 21h');
writeln(f_proc,' cmp AL,"-"');
writeln(f_proc,' jne gdl2');
writeln(f_proc,' mov AH,2h');
writeln(f_proc,' mov DL,"-"');
writeln(f_proc,' int 21h');
writeln(f_proc,' pop BX');
writeln(f_proc,' push -1');
writeln(f_proc,'gdl1: mov AH,08h');
writeln(f_proc,' int 21h');
writeln(f_proc,'gdl2: cmp AL,"0"');
writeln(f_proc,' jb gdl3');
writeln(f_proc,' cmp AL,"9"');
writeln(f_proc,' ja gdl1');
writeln(f_proc,' mov BL,AL');
writeln(f_proc,' mov AX,DI');
writeln(f_proc,' mul BP');
writeln(f_proc,' mov DL,BL');
writeln(f_proc,' sub DL,"0"');
writeln(f_proc,' mov DH,0');
writeln(f_proc,' add DX,AX');
writeln(f_proc,' jc gdl1');
writeln(f_proc,' inc SI');
writeln(f_proc,' mov DI,DX');
writeln(f_proc,' mov DL,BL');
writeln(f_proc,' mov AH,02h');
writeln(f_proc,' int 21h');
writeln(f_proc,' jmp gdl1');
writeln(f_proc,'gdl3: cmp SI,0');
writeln(f_proc,' je gdl1');
writeln(f_proc,' cmp AL,13');
writeln(f_proc,' je gdl4');
writeln(f_proc,' cmp AL,8');
writeln(f_proc,' jne gdl1');
writeln(f_proc,' dec SI');
writeln(f_proc,' mov AX,DI');
writeln(f_proc,' mov DX,0');
writeln(f_proc,' div BP');
writeln(f_proc,' mov DI,AX');
writeln(f_proc,' mov DL,8');
writeln(f_proc,' mov AH,2');
writeln(f_proc,' int 21h');
writeln(f_proc,' mov DL,32');
writeln(f_proc,' int 21h');
writeln(f_proc,' mov DL,8');
writeln(f_proc,' int 21h');
writeln(f_proc,' jmp gdl1');
writeln(f_proc,'gdl4: mov AH,2h');
writeln(f_proc,' mov DL,13');
writeln(f_proc,' int 21h');
writeln(f_proc,' mov DL,10');
writeln(f_proc,' int 21h');
writeln(f_proc,' mov AX,DI');
writeln(f_proc,' pop BX');
writeln(f_proc,' cmp BX,1');
writeln(f_proc,' je gdl5');
writeln(f_proc,' neg AX');
writeln(f_proc,'gdl5: pop DX');
writeln(f_proc,' pop BX');
writeln(f_proc,' pop BP');
writeln(f_proc,' pop SI');
writeln(f_proc,' pop DI');
writeln(f_proc,' ret');
writeln(f_proc,'GetDec ENDP');
end; (* write_GetDec *)
procedure write_PrnMatr;
begin
writeln(f_proc,';*******');
writeln(f_proc,'; ‚лў®¤ ¬ ббЁў нЄа ў ўЁ¤Ґ ¬ ваЁжл ');
writeln(f_proc,'; BX - ¤аҐб ¬ ббЁў ');
writeln(f_proc,'; CX - Є®«ЁзҐбвў® бва®Є');
writeln(f_proc,'; ‚X - Є®«ЁзҐбвў® бв®«Ўж®ў');
writeln(f_proc,'PrnMatr PROC NEAR');
writeln(f_proc,' push DX');
writeln(f_proc,' mov DX, 0');
writeln(f_proc,' mov AH, 2h ');
writeln(f_proc,'pml1:');
writeln(f_proc,' push CX');
writeln(f_proc,' mov BP, SP');
writeln(f_proc,' mov CX, [BP+2]');
writeln(f_proc,' mov DI, 0');
writeln(f_proc,'pml2:');
writeln(f_proc,' push DX');
writeln(f_proc,' mov SI, DX');
writeln(f_proc,' add SI, DI');
writeln(f_proc,' add SI, DI');
writeln(f_proc,' mov DX, [BX][SI]');
writeln(f_proc,' add DX, "0"');
writeln(f_proc,' int 21h');
writeln(f_proc,' pop DX');
writeln(f_proc,' inc DI');
writeln(f_proc,' loop pml2');
writeln(f_proc,' push DX');
writeln(f_proc,' mov DX, 0Dh');
writeln(f_proc,' int 21h');
writeln(f_proc,' mov DX, 0Ah');
writeln(f_proc,' int 21h');
writeln(f_proc,' pop DX');
writeln(f_proc,' mov BP, SP');
writeln(f_proc,' mov CX, [BP+2]');
writeln(f_proc,' add DX, CX');
writeln(f_proc,' add DX, CX');
writeln(f_proc,' pop CX');
writeln(f_proc,' loop pml1');
writeln(f_proc,' pop AX');
writeln(f_proc,' ret');
writeln(f_proc,'PrnMatr ENDP');
end; (* write_PrnMatr *)
procedure write_ConDisMatr;
begin
writeln(f_proc,';*******');
writeln(f_proc,'; CON & DIS (Љ®коЄжЁп Ё „Ё§коЄжЁп ¬ ббЁў®ў)');
writeln(f_proc,'; DI - ¤аҐб ЇаЁҐ¬ЁЄ ');
writeln(f_proc,'; SI - ¤аҐб Ёбв®зЁЄ 1');
writeln(f_proc,'; BX - ¤аҐб Ёбв®зЁЄ 2');
writeln(f_proc,'; CX - Є®«ЁзҐбвў® п祥Є');
writeln(f_proc,'; DX - вЁЇ ®ЇҐа жЁЁ (1 - DIS, 0 - CON)');
writeln(f_proc,'ConDisMatr PROC NEAR');
writeln(f_proc,' mov AX, DS ; бва®©Є ES DS');
writeln(f_proc,' mov ES, AX');
writeln(f_proc,'cml:');
writeln(f_proc,' lodsw ; ЇҐаҐбл«Є ®зҐаҐ¤®Ј® б«®ў ў AX Ё§ Ёбв®зЁЄ 1');
writeln(f_proc,'');
writeln(f_proc,' or DX, DX ; ®ЇаҐ¤Ґ«Ё¬ вЁЇ ®ЇҐа жЁЁ Ё ўлЇ®«Ё¬ ҐҐ');
writeln(f_proc,' je cml_CON');
writeln(f_proc,' or AX, [BX] ; DIS');
writeln(f_proc,' jmp cml_DIS');
writeln(f_proc,'cml_CON:');
writeln(f_proc,' and AX, [BX] ; CON');
writeln(f_proc,'cml_DIS:');
writeln(f_proc,'');
writeln(f_proc,' and AX, 01h ; ўл¤Ґ«пҐ¬ Ґ¤ЁбвўҐл© г¦л© ЇҐаўл© ЎЁв');
writeln(f_proc,' stosw ; १г«мв в - Є« ¤Ґ¬ ў ЇаЁҐ¬ЁЄ');
writeln(f_proc,' add BX, 2 ; б¤ўЁЈ Є б«Ґ¤го饩 п祩ЄҐ Ёбв®зЁЄ 2');
writeln(f_proc,' loop cml ; жЁЄ«, Ї®Є Ґ Їа®и«Ё ўбҐ п祩ЄЁ');
writeln(f_proc,' ret');
writeln(f_proc,'ConDisMatr ENDP');
end; (* write_ConDisMatr *)
var fl_write_PrnDec: Boolean; (* == Ўл«л «Ё § ЇЁб ў asm-Є®¤ asm-дгЄжЁп PrnDec *)
var fl_write_PrnMsg: Boolean; (* == Ўл«л «Ё § ЇЁб ў asm-Є®¤ asm-дгЄжЁп PrnMsg *)
var fl_write_PrnMatr: Boolean;(* == Ўл«л «Ё § ЇЁб ў asm-Є®¤ asm-дгЄжЁп PrnMatr*)
var fl_write_GetDec: Boolean; (* == Ўл«л «Ё § ЇЁб ў asm-Є®¤ asm-дгЄжЁп GetDec *)
var fl_write_ConDisMatr: Boolean; (* == Ўл«л «Ё § ЇЁб ў asm-Є®¤ asm-дгЄжЁп ConDisMatr *)
op: String;
begin
fl_write_PrnDec := false;
fl_write_PrnMsg := false;
fl_write_PrnMatr:= false;
fl_write_GetDec := false;
fl_write_ConDisMatr := false;
for gl_curTriadNum := 1 to TriadList.top do begin
getTriadElemNum(TriadList, gl_curTriadNum, gl_curTriada);
op := gl_curTriada.name;
if (op = 'WRT') then begin
if not fl_write_PrnMsg then begin
write_PrnMsg;
fl_write_PrnMsg:= true;
end;
if not fl_write_PrnDec then begin
write_PrnDec;
fl_write_PrnDec:= true;
end;
end
else if (op = 'WRTS') then begin
if not fl_write_PrnMsg then begin
write_PrnMsg;
fl_write_PrnMsg:= true;
end;
end
else if (op = 'WRTM') then begin
if not fl_write_PrnMatr then begin
write_PrnMatr;
fl_write_PrnMatr:= true;
end;
end
else if (op = 'CON')or(op = 'DIS') then begin
if not fl_write_ConDisMatr then begin
write_ConDisMatr;
fl_write_ConDisMatr:= true;
end;
end
else if (op = 'RD') then begin
if not fl_write_GetDec then begin
write_GetDec;
fl_write_GetDec:= true;
end;
end
end;
end;
(*=== DEFL - ®ЇаҐ¤Ґ«ҐЁҐ ¬ҐвЄЁ ====================================================================*)
procedure tr_defl;
begin
writeln(f_body, ' ; (', gl_curTriada.name, ', ', gl_curTriada.op1, ')');
writeln(f_body, ' lab', gl_curTriada.op1, ':');
end;
(*=== BRL - ЎҐ§гб«®ўл© ЇҐаҐе®¤ ¬ҐвЄг ==========================================================*)
procedure tr_brl;
begin
writeln(f_body, ' ; (', gl_curTriada.name, ', ', gl_curTriada.op1, ')');
writeln(f_body, ' jmp lab', gl_curTriada.op1);
end;
(*=== BF - гб«®ўл© ЇҐаҐе®¤ ¬ҐвЄг ==============================================================*)
procedure tr_bf;
var op1,op2: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* if op1 then goto op2 *)
if (op1='true') or (op1='false') then op1:='b_'+op1;
writeln(f_body, ' mov AX, ',op1);
writeln(f_body, ' cmp AX, 0');
(* ђ миҐ Ўл«® в Є:
* writeln(f_body, ' je ', op2);
* Ћ¤ Є® Ґб«Ё ¬ҐвЄ op2 ¤ «миҐ +/- 128, в® ЇҐаҐ©вЁ ҐҐ ®ЇҐа в®а®¬ гб«®ў®Ј® ЇҐаҐе®¤ Ґў®§¬®¦®.
* Џ®н⮬г ⥯Ґам ¬ҐвЄг op2 ЇҐаҐе®¤Ё¬ б Ї®¬®ймо jmp
*)
writeln(f_body, ' jne _l',labelCount);
writeln(f_body, ' jmp lab', op2);
writeln(f_body,' _l',labelCount,':');
inc(labelCount);
if (gl_curTriada.useInfo.isUse) then
(* ! ! ! Error - Ї®ЇлвЄ б®еа Ёвм १г«мв в ®ЇҐа жЁЁ BF ў® ўаҐ¬Ґго ЇҐаҐ¬Ґго *)
writeln(f_body, ' ; ! ! ! Error - Ї®ЇлвЄ б®еа Ёвм १г«мв в '+
'®ЇҐа жЁЁ BF ў® ўаҐ¬Ґго ЇҐаҐ¬Ґго ', op2);
end;
(*=== EQA - ЇаЁбў Ёў ЁҐ Ї® ¤аҐбг ================================================================*)
procedure tr_eqa;
var op1,op2: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* [op2] := op1, Ј¤Ґ op2 - ¤аҐб п祩ЄЁ*)
if (op1='true') or (op1='false') then op1:='b_'+op1;
writeln(f_body, ' mov BX, ', op2);
writeln(f_body, ' mov AX, ', op1);
writeln(f_body, ' mov [BX], AX');
(* end; *)
if (gl_curTriada.useInfo.isUse) then
(* ! ! ! Error - Ї®ЇлвЄ б®еа Ёвм १г«мв в ®ЇҐа жЁЁ ЇаЁбў Ёў Ёп ў® ўаҐ¬Ґго ЇҐаҐ¬Ґго *)
writeln(f_body, ' ; ! ! ! Error - Ї®ЇлвЄ б®еа Ёвм १г«мв в '+
'®ЇҐа жЁЁ ЇаЁбў Ёў Ёп ў® ўаҐ¬Ґго ЇҐаҐ¬Ґго ', op2);
(* writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX'); *)
end;
(*=== EQ - ЇаЁбў Ёў ЁҐ ===========================================================================*)
procedure tr_eq;
var op1,op2: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* op2 := op1 *)
if not isVariable(op2) then begin
(* ! ! ! Error - ў ®ЇҐа в®аҐ ЇаЁбў Ёў ЁЁ б«Ґў - ЌҐЏҐаҐ¬Ґ п *)
writeln(f_body, ' ; ! ! ! Error - ў ®ЇҐа в®аҐ ЇаЁбў Ёў ЁЁ б«Ґў - ЌҐЏҐаҐ¬Ґ п ', op2);
exit;
end;
(* §¤Ґбм isVariable(op2) *)
if isConstVariable(op2) then begin
(* ! ! ! Warning - ў ®ЇҐа в®аҐ ЇаЁбў Ёў ЁЁ б«Ґў - Љ®бв в п ЏҐаҐ¬Ґ п *)
writeln(f_body, ' ; ! ! ! Warning - ў ®ЇҐа в®аҐ ЇаЁбў Ёў ЁЁ б«Ґў - Љ®бв в п ЏҐаҐ¬Ґ п', op2);
exit;
end;
if (op1='true') or (op1='false') then op1:='b_'+op1;
(* FixMe 08.05.2007 serg*)
(* гв®зЁвм ЇаЁаЁбў®ҐЁп вЁЇ <k:=1> - ¬.Ў. ¬®¦® <mov _402, 1> *)
(* if isVariable(op1) then begin *)
writeln(f_body, ' mov AX, ', op1);
writeln(f_body, ' mov ', op2 ,', AX');
(* end; *)
if (gl_curTriada.useInfo.isUse) then
(* ! ! ! Error - Ї®ЇлвЄ б®еа Ёвм १г«мв в ®ЇҐа жЁЁ ЇаЁбў Ёў Ёп ў® ўаҐ¬Ґго ЇҐаҐ¬Ґго *)
writeln(f_body, ' ; ! ! ! Error - Ї®ЇлвЄ б®еа Ёвм १г«мв в '+
'®ЇҐа жЁЁ ЇаЁбў Ёў Ёп ў® ўаҐ¬Ґго ЇҐаҐ¬Ґго ', op2);
(* writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX'); *)
end;
(*=== WRT - ўлў®¤ § 票п нЄа ===============================================================*)
procedure tr_wrt;
var op1: string;
begin
op1 := gl_curTriada.op1;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ')');
(* FixMe ¤®ЇЁб вм ¤«п <WRT, true> *)
if (op1='true') or (op1='false') then op1:='b_'+op1;
writeln(f_body,' mov AX, ', op1);
writeln(f_body,' cmp AX, 0');
writeln(f_body,' jge _l', labelCount);
writeln(f_body,' neg AX');
writeln(f_body,' mov DX, OFFSET MINUS');
writeln(f_body,' call WriteMsg');
writeln(f_body,' _l',labelCount,': call PrnDec');
writeln(f_body,' mov DX, OFFSET EOLN');
writeln(f_body,' call WriteMsg');
inc(labelCount);
end;
(*=== WRTM - ўлў®¤ ¬ ваЁжл нЄа ===============================================================*)
procedure tr_wrtm;
var op1: string;
var t: tTable;
var i: Integer;
var p: tTable;
var rowCount,colCount,resultNum, op2Num, e: Integer;
var typeName, resultStr, matrNumberStr: string;
var matrNumber: Integer;
begin
op1 := gl_curTriada.op1;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ')');
(* WRTM op1 *)
(*Find variable ==> type ==> bounds*)
p := varTable;
matrNumberStr := Copy(op1,2,3);
Val(matrNumberStr,matrNumber,e);
while p <> nil do begin
if p^.num = matrNumber then begin
break
end;
p := p^.next
end;
if (p=nil) then begin
writeln(f_body, ' ; Matrix not found in varTable');
exit;
end;
typeName := p^.col1;
p := SearchId(typeTable,typeName);
if (p=nil) then begin
writeln(f_body, ' ; Type of Matrix not found in TypeTable');
exit;
end;
(*!!!* if e = 0 then **)
Val(p^.col2, colCount,e);
Val(p^.col3, rowCount,e);
writeln(f_body,' mov BX, OFFSET ',op1);
writeln(f_body,' mov CX, ',p^.col2,'; col count');
writeln(f_body,' mov DX, ',p^.col3,'; row count');
writeln(f_body,' call PrnMatr');
end;
(*=== WRTS - ўлў®¤ бва®ЄЁ нЄа ===============================================================*)
procedure tr_wrts;
var op1: string;
begin
op1 := gl_curTriada.op1;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ')');
writeln(f_body,' mov DX, OFFSET _str',op1);
writeln(f_body,' call WriteMsg');
end;
(*=================================================================================================*)
procedure tr_rd;
var op1,op2: string;
begin
op1 := gl_curTriada.op1;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ')');
writeln(f_body, ' call GetDec');
writeln(f_body, ' mov ', op1,', AX');
end;
(*=================================================================================================*)
procedure tr_neg;
var op1,op2: string;
begin
op1 := gl_curTriada.op1;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ')');
(* - op1*)
writeln(f_body, ' mov AX, ', op1);
writeln(f_body, ' neg AX');
if (gl_curTriada.useInfo.isUse) then
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
(*=================================================================================================*)
procedure tr_not;
var op1: string;
begin
op1 := gl_curTriada.op1;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ')');
(* not op1*)
if (op1='true') or (op1='false') then op1:='b_'+op1;
writeln(f_body, ' mov AX, ', op1);
writeln(f_body, ' not AX');
writeln(f_body, ' and AX, 01h');
if (gl_curTriada.useInfo.isUse) then
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
(*=== AddOp in [ADD, SUB] - ®ЇҐа жЁЁ ‘«®¦ҐЁҐ Ё ‚лзЁв ЁҐ =========================================*)
procedure tr_AddOp(oper: string);
var op1,op2: string;
labelNum1, labelNum2: Integer;
operStr: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* op2 @ op1, Ј¤Ґ @ in [+, -] *)
if (oper = 'ADD') then operStr := 'add'
else if (oper = 'SUB') then operStr := 'sub'
else operStr := '!!! Err';
labelNum1 := labelCount; inc(labelCount);
labelNum2 := labelCount; inc(labelCount);
writeln(f_body, ' mov AX, ', op2);
writeln(f_body, ' ',operStr,' AX, ', op1);
if (gl_curTriada.useInfo.isUse) then
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
(*=== LogOp in [AND, OR] - «®ЈЁзҐбЄЁҐ ®ЇҐа жЁЁ €, €‹€ =============================================*)
procedure tr_LogOp(oper: string);
var op1,op2: string;
labelNum1, labelNum2: Integer;
operStr: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* op2 @ op1, Ј¤Ґ @ in [or, and] *)
if (op1='true') or (op1='false') then op1:='b_'+op1;
if (op2='true') or (op2='false') then op2:='b_'+op2;
if (oper = 'AND') then operStr := 'je '
else if (oper = 'OR') then operStr := 'jne'
else operStr := '!!! Err';
labelNum1 := labelCount; inc(labelCount);
labelNum2 := labelCount; inc(labelCount);
writeln(f_body, ' mov AX, ', op2);
writeln(f_body, ' cmp AX, 0');
writeln(f_body, ' ',operStr ,' _l', labelNum1);
writeln(f_body, ' mov AX, ', op1);
writeln(f_body, ' cmp AX, 0');
writeln(f_body, ' ',operStr ,' _l', labelNum1);
if (oper = 'AND') then
writeln(f_body, ' mov AX, 1 ; true')
else if (oper = 'OR') then
writeln(f_body, ' mov AX, 0 ; false');
writeln(f_body, ' jmp _l', labelNum2);
writeln(f_body,' _l',labelNum1,':');
if (oper = 'AND') then
writeln(f_body, ' mov AX, 0 ; false')
else if (oper = 'OR') then
writeln(f_body, ' mov AX, 1 ; true');
writeln(f_body,' _l',labelNum2,':');
if (gl_curTriada.useInfo.isUse) then
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
(*=== RelOp - «®ЈЁзҐбЄЁҐ ®ЇҐа жЁЁ ба ўҐЁп =======================================================*)
procedure tr_RelOp(oper: string);
var op1,op2: string;
labelNum1, labelNum2: Integer;
operStr: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* op2 @ op1, Ј¤Ґ @ in [>, <, >=, <=, =, <>] *)
if (oper = '>') then operStr := 'jg '
else if (oper = '<') then operStr := 'jl '
else if (oper = '>=') then operStr := 'jge'
else if (oper = '<=') then operStr := 'jle'
else if (oper = '=') then operStr := 'je '
else if (oper = '<>') then operStr := 'jne'
else operStr := '!!! Err';
labelNum1 := labelCount; inc(labelCount);
labelNum2 := labelCount; inc(labelCount);
writeln(f_body, ' mov AX, ', op2);
writeln(f_body, ' cmp AX, ', op1);
writeln(f_body, ' ',operStr ,' _l', labelNum1);
writeln(f_body, ' mov AX, 0 ; false');
writeln(f_body, ' jmp _l', labelNum2);
writeln(f_body,' _l',labelNum1,':');
writeln(f_body, ' mov AX, 1 ; true');
writeln(f_body,' _l',labelNum2,':');
if (gl_curTriada.useInfo.isUse) then
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
(*=================================================================================================*)
procedure tr_mul;
var op1,op2: string;
operand1: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* op2 * op1*)
writeln(f_body, ' mov AX, ', op2);
if isVariable(op1) and not isConstVariable(op1) then begin
operand1 := op1; (* - в Є ¬®¦® в®«мЄ® ¤«п Ќ бв®пйЁе ЇҐаҐ¬Ґле (~ _401) *)
end else begin
writeln(f_body, ' mov BX, ', op1);
operand1 := 'BX';(* - Є®бв вл Ё Є®бв влҐ ЇҐаҐ¬ҐлҐ - зҐаҐ§ ॣЁбва *)
end;
writeln(f_body, ' imul ', operand1);
(* ђҐ§г«мв в ў DX:AX, ® ЎҐаҐ¬ в®«мЄ® ¬« ¤иго з бвм - Ё§ AX *)
if (gl_curTriada.useInfo.isUse) then
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
(*=================================================================================================*)
procedure tr_DivOp(oper: string);
var op1,op2: string;
operand1: string;
resultStr: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* op2 @ op1, Ј¤Ґ @ in [div, mod] *)
writeln(f_body, ' mov AX, ', op2, ' ; б«®ў®-¤Ґ«Ё¬®Ґ - ў AX');
writeln(f_body, ' cwd ; а биЁаЁвм ¤Ґ«Ё¬®Ґ ў DX' );
if isVariable(op1) and not isConstVariable(op1) then begin
operand1 := op1; (* - в Є ¬®¦® в®«мЄ® ¤«п Ќ бв®пйЁе ЇҐаҐ¬Ґле (~ _401) *)
end else begin
writeln(f_body, ' mov BX, ', op1, ' ; б«®ў®-¤Ґ«ЁвҐ«м - ў BX');
operand1 := 'BX'; (* - Є®бв вл Ё Є®бв влҐ ЇҐаҐ¬ҐлҐ - зҐаҐ§ ॣЁбва *)
end;
writeln(f_body, ' idiv ', operand1,' ; ®бв в®Є:з б⮥ ў DX:AX');
if (gl_curTriada.useInfo.isUse) then begin
if (oper = 'DIV') then resultStr := 'AX'
else if (oper = 'MOD') then resultStr := 'DX';
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', ',resultStr);
end;
end;
(*=================================================================================================*)
procedure tr_ConDis(oper: string; dest: string);
var op1,op2: string;
var t: tTable;
var i: Integer;
var p: tTable;
var rowCount,colCount, e: Integer;
var typeName, matrNumberStr: string;
var matrNumber: Integer;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* dest := op1 @ op2, @ in [DIS, CON]*)
(*Find variable ==> type ==> bounds*)
p := varTable;
matrNumberStr := Copy(op1,2,3);
Val(matrNumberStr,matrNumber,e);
while p <> nil do begin
if p^.num = matrNumber then begin
break
end;
p := p^.next
end;
if (p=nil) then begin
writeln(f_body, ' ; Matrix not found in varTable');
exit;
end;
typeName := p^.col1;
p := SearchId(typeTable,typeName);
if (p=nil) then begin
writeln(f_body, ' ; Type of Matrix not found in TypeTable');
exit;
end;
(*!!!* if e = 0 then **)
Val(p^.col2, colCount,e);
Val(p^.col3, rowCount,e);
writeln(f_body, ' mov DI, OFFSET ', dest,' ; ЇаЁҐ¬ЁЄ');
writeln(f_body, ' mov SI, OFFSET ', op1, ' ; Ёбв®зЁЄ1');
writeln(f_body, ' mov BX, OFFSET ', op2, ' ; Ёбв®зЁЄ2');
writeln(f_body, ' mov CX, ',colCount*rowCount, ' ; зЁб«® п祥Є');
if (oper = 'CON') then
writeln(f_body, ' mov DX, 0 ; вЁЇ ®ЇҐа жЁЁ - CON')
else
writeln(f_body, ' mov DX, 1 ; вЁЇ ®ЇҐа жЁЁ - DIS');
writeln(f_body, ' call ConDisMatr');
end;
(*=================================================================================================*)
procedure tr_subs;
var op1,op2: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* SUBS op1 op2 == op1[op2] - ᮤҐа¦Ё¬®Ґ п祩ЄЁ*)
writeln(f_body, ' mov BX, ', op2);
writeln(f_body, ' add BX, ', op2); (* в.Ґ. BX*2, в.Є. б«®ў®, Ґ Ў ©в*)
writeln(f_body, ' mov AX, ',op1,'[BX]');
if (gl_curTriada.useInfo.isUse) then begin
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
end;
(*=================================================================================================*)
procedure tr_addr;
var op1,op2: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* SUBS op1 op2 == addr(op1[op2]) - ¤аҐб п祩ЄЁ*)
writeln(f_body, ' mov AX, offset ', op1);
writeln(f_body, ' add AX, ', op2);
writeln(f_body, ' add AX, ', op2); (* в.Ґ. AX*2, в.Є. б«®ў®, Ґ Ў ©в*)
if (gl_curTriada.useInfo.isUse) then begin
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
end;
(*=================================================================================================*)
procedure tr_ColRow(oper: string);
var op1,op2: string;
var t: tTable;
var i: Integer;
var p: tTable;
var rowLength,resultNum, op2Num, e: Integer;
var typeName, matrNumberStr: string;
var matrNumber: Integer;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
(* @ op1 op2 , Ј¤Ґ @ in [COL, ROW] *)
if (gl_curTriada.useInfo.isUse) then begin
if (oper = 'COL') then begin
writeln(f_body, ' mov AX, ', op2);
writeln(f_body, ' dec AX'); (* (k)-© бв®«ЎҐж => ᬥ饨Ґ (k-1) *)
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end else if (oper = 'ROW') then begin
(*Find variable ==> type ==> bounds*)
p := varTable;
matrNumberStr := Copy(op1,2,3);
Val(matrNumberStr,matrNumber,e);
while p <> nil do begin
if p^.num = matrNumber then begin
break
end;
p := p^.next
end;
if (p=nil) then begin
writeln(f_body, ' ; Matrix not found in varTable');
exit;
end;
typeName := p^.col1;
p := SearchId(typeTable,typeName);
if (p=nil) then begin
writeln(f_body, ' ; Type of Matrix not found in TypeTable');
exit;
end;
(*!!!* if e = 0 then **)
Val(p^.col3, rowLength,e);
resultNum := (op2Num-1)*rowLength;
writeln(f_body, ' mov AX, ', op2);
writeln(f_body, ' dec AX'); (* (k)-п бва®Є => ᬥ饨Ґ (k-1)*rowLength *)
writeln(f_body, ' mov BX, ', rowLength);
writeln(f_body, ' imul BX');
(* ђҐ§г«мв в ў DX:AX, ® ЎҐаҐ¬ в®«мЄ® ¬« ¤иго з бвм - Ё§ AX *)
writeln(f_body, ' mov _tmp_', gl_curTriada.useInfo.numTmpVar, ', AX');
end;
end;
end;
(*=================================================================================================*)
(* ‡ Ј«гиЄ *)
procedure tr_col;
var op1,op2: string;
begin
op1 := gl_curTriada.op1;
op2 := gl_curTriada.op2;
writeln(f_body, ' ; ‡ Ј«гиЄ : (', gl_curTriada.name, ', ', op1, ', ', op2, ')');
end;
(*=================================================================================================*)
(* ‡ Ј«гиЄ *)
procedure tr_blbeg;
begin
writeln(f_body, ' ; ‡ Ј«гиЄ : (', gl_curTriada.name, ')');
end;
(*=================================================================================================*)
(* ‡ Ј«гиЄ *)
procedure tr_blend;
begin
writeln(f_body, ' ; ‡ Ј«гиЄ : (', gl_curTriada.name,')');
end;
(*=================================================================================================*)
procedure print_all_table;
var f: Text;
i: integer;
const fname = 'tables.txt';
procedure print_table(table: tTable);
var t: tTable;
begin
t := table;
writeln(f, 'num':10, 'id':10, 'col1':10, 'col2':10, 'col3':10, 'col4':10);
while t <> nil do begin
with t^ do writeln(f, num:10, id:10, col1:10, col2:10, col3:10, col4:10);
t := t^.next;
end;
end;(*print_table*)
begin
assign(f, fname);
rewrite(f);
writeln(f,'typeTable');
print_table(typeTable);
writeln(f,'constTable');
print_table(constTable);
writeln(f,'varTable');
print_table(varTable);
writeln(f,'labelTable');
print_table(labelTable);
(*
writeln(f,'matrTable');
print_table(matrTable);
writeln(f,'hTable');
print_table(hTable);
*)
writeln(f,'strTable');
writeln(f,'num':10,'str':10);
for i := 1 to strCount do writeln(f, i:10,' <',strTable[i],'>');
close(f);
end;(*print_all_table*)
(*=================================================================================================*)
end .