📄 tm.cpp
字号:
/****************************************************/
/* 函数名 doCommand */
/* 功 能 TM机交互命令处理函数 */
/* 说 明 函数处理用户输入的TM操作命令,完成相应动作 */
/****************************************************/
int Ctm::doCommand (void)
{ char cmd; /* 用户输入命令简称 */
int stepcnt=0, i;
int printcnt;
int stepResult;
int regNo, loc;
Cindialog myinput;
do
{
//创建模式对话框,接受用户输入命令:
myinput.DoModal();
//m_input记录了用户输入的命令:
strcpy( in_Line , myinput.m_input);
lineLen = strlen(in_Line);
inCol = 0;
}
/* 重复请求用户输入命令名,直到得到文字输入 */
while (! getWord ());
cmd = word[0] ; /* 取输入命令名中的第一个字符给cmd */
//声明帮助对话框:
//Ccomhelp myhelp;
switch ( cmd )
{
/* 该命令用于设置指令执行追踪标志,追踪指令执行 */
case 't' :
traceflag = ! traceflag ; /* 取反设置追踪标志traceflag */
/* 输出TM机t命令执行结果信息 */
//fprintf(listing,"Tracing now ");
str2 += "Tracing now ";
if ( traceflag )
//fprintf(listing,"on.\r\n");
str2 += "on.\r\n";
else
//fprintf(listing,"off.\r\n");
str2 += "off.\r\n";
break;
/**************************************************************/
//注:由于输入对话框已经给出提示,故这里的帮助已经没有用了。
/* 该命令输出帮助信息列表,显示各种命令及其功能 */
//case 'h' :
//myhelp.DoModal();
//break;
/**************************************************************/
/* 跟踪显示所有执行过指令的p命令 */
case 'p' :
icountflag = ! icountflag ; /* 设置执行指令计数标志 */
/* 输出p命令执行的结果信息 */
//fprintf(listing,"Printing instruction count now ");
str2+= "Printing instruction count now ";
if ( icountflag )
//fprintf(listing,"on.\r\n");
str2+="on.\r\n";
else
//fprintf(listing,"off.\r\n");
str2+="off.\r\n";
break;
/**************************************************************/
/* 按步执行s命令 */
case 's' :
/* 缺省的命令模式,不带命令参数,单步执行 */
if ( atEOL ()) stepcnt = 1;
/* 带有命令参数的命令模式,取得参数stepcnt */
else if ( getNum ()) stepcnt = abs(num);
/* 输出未知命令执行步数信息 */
else
//fprintf(listing,"Step count?\r\n");
str2+= "Step count?\r\n" ;
break;
/**************************************************************/
/* 执行到结束g命令 */
case 'g' : stepcnt = 1 ; break;
/**************************************************************/
/* 显示寄存器内容(regs)命令 */
case 'r' :
/* 格式化显示所有寄存器内容 */
for (i = 0; i < NO_REGS; i++)
{ //fprintf(listing,"%1d: %4d ", i,reg[i]);
str1.Format("%1d: %4d ", i,reg[i]);
str2+=str1;
if ( (i % 4) == 3 )
//printf ("\r\n");
str2+="\r\n";
}
break;
/**************************************************************/
/* 输出指令存储区iMem中指令的i命令 */
case 'i' :
/* 初始化输出指令数printcnt为1 */
printcnt = 1 ;
if ( getNum ())
{
/* 得到命令的第一个执行参数,iloc指定输出指令的开始地址 */
iloc = num ;
/* 得到命令的第二个执行参数,printcnt指定输出指令的数量 */
if ( getNum ()) printcnt = num ;
}
/* 未给定指令开始地址和输出指令数量 */
if ( ! atEOL ())
//fprintf(listing,"Instruction locations?\r\n");
str2+="Instruction locations?\r\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 ())
// fprintf(listing,"Data locations?\r\n");
str2+= "Data locations?\r\n";
else
{
/* 给定数据地址dloc在数据存储区dMen地址范围内, *
* 且数据输出数量printcnt大于0,从dloc指定地址输出指定数量的数据 */
while ((dloc >= 0) && (dloc < DADDR_SIZE)
&& (printcnt > 0))
{
//fprintf(listing,"%5d: %5d\r\n",dloc,dMem[dloc]);
str1.Format("%5d: %5d\r\n",dloc,dMem[dloc]);
str2+= str1;
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 :
//fprintf(listing,"Command %c unknown.\r\n", cmd); break;
str1.Format("Command %c unknown.\r\n", cmd);
str2+=str1;
} /* 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 )
//fprintf(listing,"Number of instructions executed = %d\r\n",stepcnt);
str1.Format("Number of instructions executed = %d\r\n",stepcnt);
str2+= str1;
}
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-- ;
}
}
/* 根据执行结果的枚举值,查执行结果状态表,显示结果状态 */
//fprintf(listing, "%s\r\n",stepResultTab[stepResult] );
str1.Format( "%s\r\n",stepResultTab[stepResult]);
str2+=str1;
}
//当输入的命令是c和q时不显示结果对话框:
if ((myinput.m_input!="c")&&(myinput.m_input!="q"))
{
//创建输出对话框,显示执行结果:
Cresult myresult ;
myresult.m_tEdit.Format(_T("%s"),str2);
myresult.DoModal();
}
return TRUE;
} /* doCommand */
/********************************************/
/* 函数名 tmain */
/* 功 能 tm机主执行函数 */
/* 说 明 函数完成tm机的命令处理, */
/* 并解释执行目标指令 */
/********************************************/
void Ctm::tmain(char * codefile)
{
/***************从构造函数拷贝,每次调用都要初始化*************/
iloc = 0 ; /* 指令存储计数指针,初始为0 */
dloc = 0 ; /* 数据存储计数指针,初始为0 */
traceflag = FALSE; /* 指令执行追踪标志,初始为FALSE */
icountflag = FALSE; /* 指令执行计数标志,初始为FALSE */
/****************************************************************/
pgm = fopen(codefile/*pgmName*/,"r");
/* 未能成功打开目标代码文件pgmName,输出错误信息 */
if (pgm == NULL)
{
AfxGetApp()->m_pMainWnd->MessageBox("未找到目标代码文件。");
return;
}
/* 读入指令:将指令存储区iMem清空并从指定的文件中写入指令序列 */
if ( ! readInstructions ())
{
AfxGetApp()->m_pMainWnd->MessageBox("不能读取指令!");
return;
}
/* 准备执行TM虚拟机命令,输出提示信息 */
//fprintf(listing,"TM simulation (enter h for help)...\r\n");
AfxGetApp()->m_pMainWnd->MessageBox("开始解释虚拟机");
/* 交互执行,处理用户输入的TM命令,对已经输入到iMem中的指令进行操作 */
do
{
//输出对话框清空:
str1.Empty();
str2.Empty();
//执行一个命令:
done = ! doCommand ();
}
while (! done );
/* 虚拟机命令执行完毕 */
AfxGetApp()->m_pMainWnd->MessageBox("虚拟机执行完毕!");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -