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