?? 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 + -