?? tm.cpp
字號:
/* 將寄存器reg[r]賦值為當前指令的第二操作數的值 */
case opLDC : reg[r] = currentinstruction.iarg2 ; break;
/**********************************************/
/* 如果寄存器reg[r]的值小于0,則將程序計數器reg[PC_REG]的值 *
* 賦值為立即數m,產生小于條件跳轉 */
case opJLT : if ( reg[r] < 0 ) reg[PC_REG] = m ; break;
/**********************************************/
/* 如果寄存器reg[r]的值小于等于0,則將程序計數器reg[PC_REG]的值 *
* 賦值為立即數m,產生小于等于條件跳轉 */
case opJLE : if ( reg[r] <= 0 ) reg[PC_REG] = m ; break;
/**********************************************/
/* 如果寄存器reg[r]的值大于0,則將程序計數器reg[PC_REG]的值 *
* 賦值為立即數m,產生大于條件跳轉 */
case opJGT : if ( reg[r] > 0 ) reg[PC_REG] = m ; break;
/**********************************************/
/* 如果寄存器reg[r]的值大于等于0,則將程序計數器reg[PC_REG]的值 *
* 賦值為立即數m,產生大于等于跳轉 */
case opJGE : if ( reg[r] >= 0 ) reg[PC_REG] = m ; break;
/**********************************************/
/* 如果寄存器reg[r]的值等于0,則將程序計數器reg[PC_REG]的值 *
* 賦值為立即數m,產生等于條件跳轉 */
case opJEQ : if ( reg[r] == 0 ) reg[PC_REG] = m ; break;
/**********************************************/
/* 如果寄存器reg[r]的值不等于0,則將程序計數器reg[PC_REG]的值 *
* 賦值為立即數m,產生不等于條件跳轉 */
case opJNE : if ( reg[r] != 0 ) reg[PC_REG] = m ; break;
}
/* case */
/* 所有正常結束指令,返回正常結果狀態 */
return srOKAY ;
} /* stepTM */
/****************************************************/
/* 函數名 doCommand */
/* 功 能 TM機交互命令處理函數 */
/* 說 明 函數處理用戶輸入的TM操作命令,完成相應動作 */
/****************************************************/
int doCommand (void)
{ char cmd; /* 用戶輸入命令簡稱 */
int stepcnt=0, i;
int printcnt;
int stepResult;
int regNo, loc;
do
{
/* 屏幕顯示提示信息,提示用戶輸入TM命令 */
printf ("Enter command: ");
/* 刷新標準輸入輸出流 */
fflush (stdin);
fflush (stdout);
/* 從標準輸入流中取得用戶輸入的命令 */
gets(in_Line);
lineLen = strlen(in_Line);
inCol = 0;
}
/* 重復請求用戶輸入命令名,直到得到文字輸入 */
while (! getWord ());
cmd = word[0] ; /* 取輸入命令名中的第一個字符給cmd */
switch ( cmd )
{
/* 該命令用于設置指令執行追蹤標志,追蹤指令執行 */
case 't' :
traceflag = ! traceflag ; /* 取反設置追蹤標志traceflag */
/* 輸出TM機t命令執行結果信息 */
printf("Tracing now ");
if ( traceflag ) printf("on.\n"); else printf("off.\n");
break;
/**************************************************************/
/* 該命令輸出幫助信息列表,顯示各種命令及其功能 */
case 'h' :
printf("Commands are:\n");
/* 按步執行(step)命令:可輸入"s(tep <n>"來執行, *
* 可執行n(默認為1)條tm指令. */
printf(" s(tep <n> "\
"Execute n (default 1) TM instructions\n");
/* 執行到結束(go)命令:可輸入"g(o"來執行, *
* 順序執行tm指令直到遇到HALT指令 */
printf(" g(o "\
"Execute TM instructions until HALT\n");
/* 顯示寄存器(regs)命令:可輸入"r(egs"來執行, *
* 顯示各寄存器的內容 */
printf(" r(egs "\
"Print the contents of the registers\n");
/* 輸出指令(iMem)命令:可輸入"i(Mem <b<n>>"來執行, *
* 從地址b處輸出n條指令 */
printf(" i(Mem <b <n>> "\
"Print n iMem locations starting at b\n");
/* 輸出數據(dMem)命令:可輸入"d(Mem<b<n>>"來執行, *
* 從地址b處輸出n跳數據 */
printf(" d(Mem <b <n>> "\
"Print n dMem locations starting at b\n");
/* 跟蹤(trace)命令:可輸入"t(race"來執行, *
* 反置追蹤標志traceflag,如果traceflag為TRUE, *
* 則執行每條指令時候顯示指令 */
printf(" t(race "\
"Toggle instruction trace\n");
/* 顯示執行指令數量(print)命令:可輸入"p(rint)"來執行, *
* 反置追蹤標志icountflag,如果icountflag為TRUE, *
* 則顯示已經執行過的指令數量.只在執行"go"命令時有效 */
printf(" p(rint "\
"Toggle print of total instructions executed"\
" ('go' only)\n");
/* 重置tm機用(clear)命令:可輸入"c(lear"來執行, *
* 重新設置tm虛擬機,用以執行新的程序. */
printf(" c(lear "\
"Reset simulator for new execution of program\n");
/* 幫助(help)命令:可輸入"h(elp"來執行,顯示命令列表 */
printf(" h(elp "\
"Cause this list of commands to be printed\n");
/* 終止(quit)命令,可輸入"q(uit"來執行,結束虛擬機的執行 */
printf(" q(uit "\
"Terminate the simulation\n");
break;
/**************************************************************/
/* 跟蹤顯示所有執行過指令的p命令 */
case 'p' :
icountflag = ! icountflag ; /* 設置執行指令計數標志 */
/* 輸出p命令執行的結果信息 */
printf("Printing instruction count now ");
if ( icountflag ) printf("on.\n"); else printf("off.\n");
break;
/**************************************************************/
/* 按步執行s命令 */
case 's' :
/* 缺省的命令模式,不帶命令參數,單步執行 */
if ( atEOL ()) stepcnt = 1;
/* 帶有命令參數的命令模式,取得參數stepcnt */
else if ( getNum ()) stepcnt = abs(num);
/* 輸出未知命令執行步數信息 */
else printf("Step count?\n");
break;
/**************************************************************/
/* 執行到結束g命令 */
case 'g' : stepcnt = 1 ; break;
/**************************************************************/
/* 顯示寄存器內容(regs)命令 */
case 'r' :
/* 格式化顯示所有寄存器內容 */
for (i = 0; i < NO_REGS; i++)
{ printf("%1d: %4d ", i,reg[i]);
if ( (i % 4) == 3 ) printf ("\n");
}
break;
/**************************************************************/
/* 輸出指令存儲區iMem中指令的i命令 */
case 'i' :
/* 初始化輸出指令數printcnt為1 */
printcnt = 1 ;
if ( getNum ())
{
/* 得到命令的第一個執行參數,iloc指定輸出指令的開始地址 */
iloc = num ;
/* 得到命令的第二個執行參數,printcnt指定輸出指令的數量 */
if ( getNum ()) printcnt = num ;
}
/* 未給定指令開始地址和輸出指令數量 */
if ( ! atEOL ())
printf ("Instruction locations?\n");
else
{
/* 指令地址iloc在指令存儲區iMem地址范圍中, *
* 且指令輸出數量printcnt大于0,從iloc指定地址輸出指定數量指令 */
while ((iloc >= 0) && (iloc < IADDR_SIZE)
&& (printcnt > 0) )
{ writeInstruction(iloc);
iloc++ ;
printcnt-- ;
}
}
break;
/**************************************************************/
/* 輸出數據存儲區dMem中的數據的d命令 */
case 'd' :
printcnt = 1 ;
if ( getNum ())
{
/* 取得命令的第一執行參數,數據存儲的開始地址dloc */
dloc = num ;
/* 取得命令的第二執行參數,輸出數據的數量printcnt */
if ( getNum ()) printcnt = num ;
}
/* 未給定數據存儲區中的數據開始地址和數量 */
if ( ! atEOL ())
printf("Data locations?\n");
else
{
/* 給定數據地址dloc在數據存儲區dMen地址范圍內, *
* 且數據輸出數量printcnt大于0,從dloc指定地址輸出指定數量的數據 */
while ((dloc >= 0) && (dloc < DADDR_SIZE)
&& (printcnt > 0))
{ printf("%5d: %5d\n",dloc,dMem[dloc]);
dloc++;
printcnt--;
}
}
break;
/**************************************************************/
/* 重置tm機用以執行新的程序(clear)指令 */
case 'c' :
iloc = 0; /* 指令存儲地址,初始為0 */
dloc = 0; /* 數據存儲地址,初始為0 */
stepcnt = 0; /* 指令執行步數,初始為0 */
/* 初始化各寄存器reg[]為0 */
for (regNo = 0; regNo < NO_REGS ; regNo++)
reg[regNo] = 0 ;
/* 數據存儲區0地址單元用于記錄數據存儲區dMem的高端地址 */
dMem[0] = DADDR_SIZE - 1 ;
/* 初始化其它數據存儲區單元為0 */
for (loc = 1 ; loc < DADDR_SIZE ; loc++)
dMem[loc] = 0 ;
break;
/**************************************************************/
case 'q' : return FALSE; /* 停止執行并退出命令 */
/**************************************************************/
/* 其它未定義命令,輸出錯誤信息 */
default : printf("Command %c unknown.\n", cmd); break;
} /* case */
/******************** 命令的后續處理 **********************/
stepResult = srOKAY; /* 命令執行結果為srOKAY */
if ( stepcnt > 0 )
{ if ( cmd == 'g' )
{ stepcnt = 0; /* 此處stepcnt作為已經執行過的指令數目 */
while (stepResult == srOKAY)
{
/* 根據執行指令追蹤標志traceflag,將當前地址iloc上指令輸出到屏幕 */
iloc = reg[PC_REG] ;
if ( traceflag ) writeInstruction( iloc ) ;
/* 單步執行當前指令,結果返回stepResult */
stepResult = stepTM ();
/* 執行過指令計數stepcnt加1 */
stepcnt++;
}
/* 根據執行執行數量追蹤標志icountflag,顯示已經執行過的指令數量 */
if ( icountflag )
printf("Number of instructions executed = %d\n",stepcnt);
}
else
{
/* 在其它命令中stepcnt作為將執行,輸出的指令或數據的數量 */
while ((stepcnt > 0) && (stepResult == srOKAY))
{
/* 取得程序計數器reg[PC_REG]中當前指令地址 */
iloc = reg[PC_REG] ;
/* 根據執行指令追蹤標志traceflag,將當前指令地址iloc上指令輸出到屏幕 */
if ( traceflag ) writeInstruction( iloc ) ;
/* 執行當前指令,結果返回stepResult */
stepResult = stepTM ();
/* stepcnt此時用于記錄將要執行,輸出的指令或數據的數量,自減 */
stepcnt-- ;
}
}
/* 根據執行結果的枚舉值,查執行結果狀態表,顯示結果狀態 */
printf( "%s\n",stepResultTab[stepResult] );
}
return TRUE;
} /* doCommand */
/********************************************/
/* 函數名 tmain */
/* 功 能 tm機主執行函數 */
/* 說 明 函數完成tm機的命令處理, */
/* 并解釋執行目標指令 */
/********************************************/
void tmain(char * codefile)
{
//char pgmName[120];
/*提示輸入源代碼文件目錄名*/
//printf("input program names:\n");
/*存儲文件目錄名到pgm中*/
//scanf("%s",pgmName);
getchar();
pgm = fopen(codefile/*pgmName*/,"r");
/* 未能成功打開目標代碼文件pgmName,輸出錯誤信息 */
if (pgm == NULL)
{ printf("file '%s' not found\n",codefile);
exit(1);
}
/* 讀入指令:將指令存儲區iMem清空并從指定的文件中寫入指令序列 */
if ( ! readInstructions ())
exit(1) ;
/* 準備執行TM虛擬機命令,輸出提示信息 */
printf("TM simulation (enter h for help)...\n");
/* 交互執行,處理用戶輸入的TM命令,對已經輸入到iMem中的指令進行操作 */
do
done = ! doCommand ();
while (! done );
/* 虛擬機命令執行完畢 */
printf("Simulation done.\n");
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -