?? code.cpp
字號:
#include "StdAfx.h"
#include ".\code.h"
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
CCode::CCode(CPl0*p)
{
cx = 0;
pl=p;
}
/*目標(biāo)代碼生成過程gen
參數(shù):x:要生成的一行代碼的助記符
y, z:代碼的兩個操作數(shù)
本過程用于把生成的目標(biāo)代碼寫入目標(biāo)代碼數(shù)組,供后面的解釋器解釋執(zhí)行 */
void CCode::Gen(enum fct x,int y,int z)
{
if (cx<CODE_SIZE) //如果cx>cxmax表示當(dāng)前生成的代碼行號大于允許的最大代碼行數(shù)
{
code[cx].f=x;
code[cx].l=y;
code[cx].a=z;
cx++; //移動cx指針指向下一個空位
}
}
/* 通過靜態(tài)鏈求出數(shù)據(jù)區(qū)基地址的函數(shù)base
參數(shù)說明:l:要求的數(shù)據(jù)區(qū)所在層與當(dāng)前層的層差
返回值:要求的數(shù)據(jù)區(qū)基址 */
int CCode::base(int l)
{
int b1;
b1=b; //首先從當(dāng)前層開始
while (l>0)
{
b1=s[b1]; //用當(dāng)前層數(shù)據(jù)區(qū)基址中的內(nèi)容(正好是靜態(tài)鏈SL數(shù)據(jù),為上一層的基址)
//的作為新的當(dāng)前層,即向上找了一層
l--; //向上了一層,l減一
}
return b1; //把找到的要求的數(shù)據(jù)區(qū)基址返回
}
void CCode::Interpret()
{
int p,t;
fct f;
int l,a;
t=0;b=1;p=0; //程序開始運行時棧頂寄存器置0,數(shù)據(jù)段基址為1,從0號代碼開始執(zhí)行程序
s[1]=0;s[2]=0;s[3]=0; //數(shù)據(jù)內(nèi)存中為SL,DL,RA三個單元均為0,標(biāo)識為主程序
do{
f=code[p].f;l=code[p].l;a=code[p].a; // 獲取一行目標(biāo)代碼
p++; //指令指針加一,指向下一條代碼
switch (f) //如果i的f,即指令助記符是下面的某種情況,執(zhí)行不同的功能
{
case lit:
s[++t]=a; //棧頂指針上移,在棧中分配了一個單元
break; //該單元的內(nèi)容存放i指令的a操作數(shù),即實現(xiàn)了把常量值放到運行棧棧頂
case opr:
switch (a)
{
case 0:
t=b-1; //釋放這段子過程占用的數(shù)據(jù)內(nèi)存空間
p=s[t+3]; //把指令指針取到RA的值,指向的是返回地址
b=s[t+2]; //把數(shù)據(jù)段基址取到DL的值,指向調(diào)用前子過程的數(shù)據(jù)段基址
break;
case 1:
s[t]=-s[t]; //對棧頂數(shù)據(jù)進行取反
break;
case 2:
t--;
s[t]=s[t]+s[t+1]; //把兩單元數(shù)據(jù)相加存入棧頂
break;
case 3:
t--;
s[t]=s[t]-s[t+1]; //把兩單元數(shù)據(jù)相減存入棧頂
break;
case 4: t--;
s[t]=s[t]*s[t+1]; //把兩單元數(shù)據(jù)相乘存入棧頂
break;
case 5:
t--;
s[t]=s[t]/s[t+1]; //把兩單元數(shù)據(jù)相整除存入棧頂
break;
case 6:
s[t]=s[t]%2; //數(shù)據(jù)棧頂?shù)闹凳瞧鏀?shù)則把棧頂值置1,否則置0
break;
case 8:
t--;
s[t]=(s[t]==s[t+1]);//判等,相等棧頂置1,不等置0
break;
case 9:
t--;
s[t]=(s[t]!=s[t+1]);//判不等,不等棧頂置1,相等置0
break;
case 10:
t--;
s[t]=(s[t]<s[t+1]); //判小于,如果下面的值小于上面的值,棧頂置1,否則置0
break;
case 11:
t--;
s[t]=(s[t]>=s[t+1]);//判大于等于,如果下面的值大于等于上面的值,棧頂置1,否則置0
break;
case 12:
t--;
s[t]=(s[t]>s[t+1]); //判大于,如果下面的值大于上面的值,棧頂置1,否則置0
break;
case 13:
t--;
s[t]=(s[t]<=s[t+1]);//判小于等于,如果下面的值小于等于上面的值,棧頂置1,否則置0
break;
case 14:
cout<<s[t]<<"\t"; //輸出棧頂值
break;
case 15:
cout<<"\n"; //輸出換行
break;
case 16:
t++;
cout<<"?";
cin>>s[t]; //16號操作是接受鍵盤值輸入到棧頂
break;
}
break;
case lod: //如果是lod指令:將變量放到棧頂
t++; //棧頂上移,開辟空間
s[t]=s[base(l)+a]; //通過數(shù)據(jù)區(qū)層差l和偏移地址a找到變量的數(shù)據(jù),存入上面開辟的新空間(即棧頂)
break;
case sto:
s[base(l)+a]=s[t]; //把棧頂?shù)闹荡嫒胛恢迷跀?shù)據(jù)區(qū)層差l偏移地址a的變量內(nèi)存
t--; //棧項下移,釋放空間
break;
case cal:
//過程調(diào)用前的保護現(xiàn)場
s[t+1]=base(l); //在棧頂壓入靜態(tài)鏈SL
s[t+2]=b; //然后壓入當(dāng)前數(shù)據(jù)區(qū)基址,作為動態(tài)鏈DL
s[t+3]=p; //最后壓入當(dāng)前的斷點,作為返回地址RA
b=t+1; //把當(dāng)前數(shù)據(jù)區(qū)基址指向SL所在位置
p=a; //從a所指位置開始繼續(xù)執(zhí)行指令,即實現(xiàn)了程序執(zhí)行的跳轉(zhuǎn)
break;
case tint:
t+=a; //棧頂上移a個空間,即開辟a個新的內(nèi)存單元
break;
case jmp:
p=a; //把jmp指令操作數(shù)a的值作為下一次要執(zhí)行的指令地址,實現(xiàn)無條件跳轉(zhuǎn)
break;
case jpc:
if (s[t]==0) //判斷棧頂值
p=a; //如果是0就跳轉(zhuǎn),否則不跳轉(zhuǎn)
t--; //釋放棧頂空間
break;
}
}while (p!=0);
}
//逐行輸出代碼
void CCode::ListCode()
{
FILE *fp;
//int i;
char c[1];
char *filename = pl->flnm;
strcat(filename,".txt");
if((fp=fopen(filename,"wb"))==NULL)
{
printf("cant open the file");
exit(0);
}
for (int i=0;i<cx;i++)
{
cout<<i<<" ";
switch (code[i].f)
{
case lit:
cout<<"lit\t";
fwrite("lit ",sizeof(char),strlen("lit "),fp);
break;
case lod:
cout<<"lod\t";
fwrite("lod ",sizeof(char),strlen("lod "),fp);
break;
case sto:
cout<<"sto\t";
fwrite("sto ",sizeof(char),strlen("sto "),fp);
break;
case cal:
cout<<"cal\t";
fwrite("cal ",sizeof(char),strlen("cal "),fp);
break;
case tint:
cout<<"int\t";
fwrite("int ",sizeof(char),strlen("int "),fp);
break;
case jmp:
cout<<"jmp\t";
fwrite("jmp ",sizeof(char),strlen("jmp "),fp);
break;
case jpc:
cout<<"jpc\t";
fwrite("jpc ",sizeof(char),strlen("jpc "),fp);
break;
case opr:
cout<<"opr\t";
fwrite("opr ",sizeof(char),strlen("opr "),fp);
break;
}
cout<<code[i].l<<"\t"<<code[i].a<<endl;
c[0] = static_cast<char>('0'+ code[i].l);
fwrite(c,sizeof(char),1,fp);
fwrite(" ",sizeof(char),strlen(" "),fp);
if(code[i].a >= 10)
{
c[0] = static_cast<char>('0'+ code[i].a / 10);
fwrite(c,sizeof(char),1,fp);
}
c[0] = static_cast<char>('0'+ code[i].a%10);
fwrite(c,sizeof(char),1,fp);
fwrite("\t\t",sizeof(char),strlen("\t\t"),fp);
}
}
CCode::~CCode(void)
{
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -