📄 code.cpp
字号:
/****************************************************/
/* 文件 code.c */
/* 说明 TINY编译器的TM代码产生功能实现文件 */
/* 主题 编译器结构:原理和实例 */
/****************************************************/
#include "globals.h" /* 该头文件定义了全局类型与变量 */
#include "code.h" /* 该头文件定义了TM代码产生功能函数界面 */
/* TM指令当前生成代码写入地址 */
static int emitLoc = 0 ;
/* 用于在函数emitSkip,emitBackup,emitRestore *
* 中作为当前最高生成代码写入地址,初始为0 */
static int highEmitLoc = 0;
/****************************************************************/
/* 函数名 emitComment */
/* 功 能 注释生成函数 */
/* 说 明 该函数将函数参数c指定的注释内容写入代码文件code */
/****************************************************************/
void emitComment( char * c )
/* 如果代码生成追踪标志TraceCode为TRUE,将注释写入目标代码文件code */
{
if (TraceCode)
{
fprintf(code,"* %s\n",c);
}
}
/********************************************************/
/* 函数名 emitRO */
/* 功 能 寄存器地址模式指令生成函数 */
/* 说 明 该函数产生一条只用寄存器操作数的TM指令 */
/* op 为操作码; */
/* r 为目标寄存器; */
/* s 第一源寄存器; */
/* t 第二源寄存器; */
/* c 为将写入代码文件code的注释内容 */
/********************************************************/
void emitRO( char *op, int r, int s, int t, char *c)
{
/* 将TM指令格式化写入代码文件code,当前生成代码写入地址emitLoc加1 */
fprintf(code,"%3d: %5s %d,%d,%d ",emitLoc++,op,r,s,t);
/* 如果代码生成追踪标志TraceCode为TRUE,将注释c写入代码文件code */
if (TraceCode)
{
fprintf(code,"\t*%s",c);
}
/* 一条代码指令写完,加入代码行结束标志 */
fprintf(code,"\n");
/* 当前生成代码写入地址若超出最高生成代码写入地址 *
* 改变最高生成代码写入地址highEmitLoc为当前生成代码写入地址emitLoc */
if (highEmitLoc < emitLoc) highEmitLoc = emitLoc ;
}
/********************************************************/
/* 函数名 emitRM */
/* 功 能 变址地址模式指令生成函数 */
/* 说 明 该函数产生一条寄存器-内存操作数TM指令 */
/* op 操作码; */
/* r 目标寄存器; */
/* d 为偏移值; */
/* s 为基地址寄存器; */
/* c 为将写入代码文件code的注释内容 */
/********************************************************/
void emitRM( char * op, int r, int d, int s, char *c)
{
/* 将TM指令格式化写入代码文件code,当前生成代码写入地址emitLoc加1 */
fprintf(code,"%3d: %5s %d,%d(%d) ",emitLoc++,op,r,d,s);
/* 如果代码生成追踪标志TraceCode为TRUE,将注释c写入代码文件code */
if (TraceCode)
{
fprintf(code,"\t*%s",c);
}
/* 写完一条代码指令,加入指令行结束标志 */
fprintf(code,"\n");
/* 若当前生成代码写入地址emitLoc超过最高生成代码写入地址highEmitLoc *
* 更新最高生成代码写入地址highEmitLoc */
if (highEmitLoc < emitLoc) highEmitLoc = emitLoc ;
}
/****************************************************/
/* 函数名 emitSkip */
/* 功 能 空过生成函数 */
/* 说 明 该函数空过howMany指定数量的写入代码位置, */
/* 返回当前生成代码写入地址 */
/****************************************************/
int emitSkip( int howMany)
{
/* 当前生成代码写入地址emitLoc赋给变量i */
int i = emitLoc;
/* 新的当前生成代码写入地址emitLoc略过howMany指定数量的写入指令位置 */
emitLoc += howMany ;
/* 若当前生成代码写入地址emitLoc超过最高生成代码写入地址highEmitLoc *
* 更新最高生成代码写入地址highEmitLoc */
if (highEmitLoc < emitLoc) highEmitLoc = emitLoc ;
/* 函数返回旧的当前生成代码写入地址i */
return i;
}
/********************************************************/
/* 函数名 emitBackup */
/* 功 能 地址回退函数 */
/* 说 明 该函数退回到以前被空过的生成代码写入地址loc */
/********************************************************/
void emitBackup( int loc)
{
/* 如果要退回的地址loc比当前最高地址highEmitLoc还高 *
* 报退回错误,将错误信息作为注释写入代码文件code */
if (loc > highEmitLoc) emitComment("BUG in emitBackup");
/* 更新当前生成代码写入地址emitLoc为函数参数loc,完成退回动作 */
emitLoc = loc ;
}
/********************************************************/
/* 函数名 emitRestore */
/* 功 能 地址恢复函数 */
/* 说 明 该函数将当前生成代码写入地址emitLoc恢复为 */
/* 当前未写入指令的最高地址highEmitLoc */
/********************************************************/
void emitRestore(void)
{ emitLoc = highEmitLoc;}
/************************************************/
/* 函数名 emitRM_Abs */
/* 功 能 地址转换函数 */
/* 说 明 该函数在产生一条寄存器-内存TM指令时, */
/* 将绝对地址参数转换成pc相对地址参数 */
/* op 为操作码; */
/* r 为目标寄存器; */
/* a 为存储器绝对地址; */
/* c 为将写入代码文件code的注释 */
/************************************************/
void emitRM_Abs( char *op, int r, int a, char * c)
{
/* 将TM指令格式化写入代码文件code,将函数参数a给定的绝对地址 *
* 转换为相对于指令指示器pc的相对地址a-(emitLoc+1) */
fprintf(code,"%3d: %5s %d,%d(%d) ",
emitLoc,op,r,a-(emitLoc+1),pc);
/* 更新当前生成代码写入地址emitLoc */
++emitLoc ;
/* 如果代码生成追踪标志traceCode为TRUE,将注释c写入代码文件code */
if (TraceCode)
{
fprintf(code,"\t*%s",c);
}
fprintf(code,"\n");
/* 若当前生成代码写入地址emitLoc超出最高生成代码写入地址highEmitLoc *
* 更新最高生成代码写入地址highEmitLoc */
if (highEmitLoc < emitLoc) highEmitLoc = emitLoc ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -