?? tm.cpp
字號(hào):
}
return temp;
} /* getWord */
/************************************************************/
/* 函數(shù)名 skipCh */
/* 功 能 字符空過(guò)函數(shù) */
/* 說(shuō) 明 如果當(dāng)前位置上字符為函數(shù)指定的字符,則空過(guò)該字符, */
/* 函數(shù)返回TRUE;否則函數(shù)返回FALSE */
/************************************************************/
int skipCh ( char c )
{ int temp = FALSE;
/* 當(dāng)前位置上字符為函數(shù)指定字符c */
if ( nonBlank() && (ch == c) )
{ getCh(); /* 空過(guò)當(dāng)前字符c,取下一字符 */
temp = TRUE; /* 空過(guò)指定字符c,函數(shù)返回TRUE */
}
return temp;
} /* skipCh */
/************************************/
/* 函數(shù)名 atEOL */
/* 功 能 行結(jié)束判斷函數(shù) */
/* 說(shuō) 明 當(dāng)前行是否結(jié)束的判斷函數(shù) */
/************************************/
int atEOL(void)
{ return ( ! nonBlank ()); /* 如果當(dāng)前行中沒(méi)有非空字符,則函數(shù)返回TRUE */
} /* atEOL */
/****************************************************/
/* 函數(shù)名 error */
/* 功 能 錯(cuò)誤處理函數(shù) */
/* 說(shuō) 明 函數(shù)輸出錯(cuò)誤行號(hào),指令地址標(biāo)號(hào)和錯(cuò)誤信息 */
/****************************************************/
int error( char * msg, int lineNo, int instNo)
{
/* 輸出錯(cuò)誤出現(xiàn)位置行號(hào)lineNo */
printf("Line %d",lineNo);
/* 輸出錯(cuò)誤指令地址標(biāo)號(hào)instNo */
if (instNo >= 0) printf(" (Instruction %d)",instNo);
/* 輸出錯(cuò)誤信息msg */
printf(" %s\n",msg);
return FALSE;
} /* error */
/********************************************************/
/* 函數(shù)名 readInstructions */
/* 功 能 指令文件讀入函數(shù) */
/* 說(shuō) 明 將指令文件中的指令逐條讀入到指令存儲(chǔ)區(qū)iMem */
/********************************************************/
int readInstructions (void)
{
OPCODE op; /* 當(dāng)前指令操作碼 */
int arg1, arg2, arg3; /* 當(dāng)前指令操作數(shù) */
int loc, regNo, lineNo;
/* 將8個(gè)寄存器內(nèi)容初始化為0 */
for (regNo = 0 ; regNo < NO_REGS ; regNo++)
reg[regNo] = 0 ;
/* dMem為數(shù)據(jù)存儲(chǔ)區(qū),0地址單元dMem[0]的值賦為數(shù)據(jù)存儲(chǔ)區(qū)高端地址1023 *
* 此數(shù)值將在目標(biāo)程序運(yùn)行時(shí)由程序的先驅(qū)指令讀入到mp寄存器中 */
dMem[0] = DADDR_SIZE - 1 ;
/* 將數(shù)據(jù)存儲(chǔ)數(shù)區(qū)內(nèi)除0地址單元外的各單元初始化為0 */
for (loc = 1 ; loc < DADDR_SIZE ; loc++)
dMem[loc] = 0 ;
/* 將指令存儲(chǔ)區(qū)中各單元初始化為指令;HALT 0,0,0 */
for (loc = 0 ; loc < IADDR_SIZE ; loc++)
{ iMem[loc].iop = opHALT ;
iMem[loc].iarg1 = 0 ;
iMem[loc].iarg2 = 0 ;
iMem[loc].iarg3 = 0 ;
}
lineNo = 0 ; /* lineNo用于記錄當(dāng)前代碼指令行號(hào) */
/* 不是指定文件pgm的文件結(jié)尾 */
while (! feof(pgm))
{
/* 從指定文件pgm中讀入119個(gè)字符到當(dāng)前代碼行in_Line */
fgets( in_Line, LINESIZE-2, pgm ) ;
inCol = 0 ; /* 當(dāng)前代碼行in_Line中當(dāng)前字符位置inCol初始為0 */
lineNo++; /* 當(dāng)前代碼行行號(hào)加1 */
/* 當(dāng)前代碼行in_Line行結(jié)尾字符位置賦給lineLen */
lineLen = strlen(in_Line)-1 ;
/* 如果源行結(jié)束字符是'\n',則更換行結(jié)束字符為'\0' */
if (in_Line[lineLen]=='\n') in_Line[lineLen] = '\0' ;
/* 源行沒(méi)有行結(jié)束字符,加上結(jié)束字符'\0' */
else in_Line[++lineLen] = '\0';
/* 當(dāng)前字符不是"*",即不是注釋語(yǔ)句,應(yīng)該是指令語(yǔ)句 */
if ( (nonBlank()) && (in_Line[inCol] != '*') )
{
/* 當(dāng)前字符不是數(shù)字,報(bào)地址錯(cuò),并給出行號(hào)lineNo */
if (! getNum())
return error("Bad location", lineNo,-1);
/* 將所得數(shù)值賦給當(dāng)前代碼地址標(biāo)號(hào)loc */
loc = num;
/* 代碼地址標(biāo)號(hào)loc超出指令存儲(chǔ)區(qū)地址IADDR_SIZE,報(bào)錯(cuò) */
if (loc > IADDR_SIZE)
return error("Location too large",lineNo,loc);
/* 代碼地址標(biāo)號(hào)loc后面缺少冒號(hào),報(bào)缺少冒號(hào)錯(cuò) */
if (! skipCh(':'))
return error("Missing colon", lineNo,loc);
/* 當(dāng)前位置不是單詞,報(bào)缺少指令操作碼錯(cuò) */
if (! getWord ())
return error("Missing opcode", lineNo,loc);
/* 初始查表指針op,op指向操作碼表表首,值為opHALT */
op = opHALT ;
/* 查操作碼表opCodeTab,只比較當(dāng)前字word中的前四個(gè)字符 *
* 因?yàn)樗卸x的操作碼中,最長(zhǎng)操作碼HALT長(zhǎng)度只為四 */
while ((op < opRALim)
&& (strncmp(opCodeTab[op], word, 4) != 0) )
op = (enum opcode)(op+1);
/* 當(dāng)前單詞word中指定的操作碼不在操作碼表opCodeTab中,報(bào)非法操作碼錯(cuò)誤 */
if (strncmp(opCodeTab[op], word, 4) != 0)
return error("Illegal opcode", lineNo,loc);
/* 對(duì)查表得到的操作碼值op的尋址模式,進(jìn)行分類處理 */
switch ( opClass(op) )
{ case opclRR : /* 寄存器尋址模式操作碼 */
/* 第一寄存器操作數(shù)錯(cuò),非0-7之間數(shù)字, *
* 輸出錯(cuò)誤信息,行號(hào)lineNo,代碼地址標(biāo)號(hào)loc */
if ( (! getNum ()) || (num < 0) || (num >= NO_REGS) )
return error("Bad first register", lineNo,loc);
/* 將第一操作數(shù)arg1賦值為當(dāng)前數(shù)值num */
arg1 = num;
/* 第一操作數(shù)后漏掉","分隔符,報(bào)錯(cuò) */
if ( ! skipCh(','))
return error("Missing comma", lineNo, loc);
/* 第二寄存器操作數(shù)錯(cuò),非0-7之間數(shù)字, *
* 輸出錯(cuò)誤信息,行號(hào)lineNo,代碼地址標(biāo)號(hào)loc */
if ( (! getNum ()) || (num < 0) || (num >= NO_REGS) )
return error("Bad second register", lineNo, loc);
/* 將第二個(gè)操作數(shù)arg2賦值為當(dāng)前數(shù)值num */
arg2 = num;
/* 第二操作數(shù)后漏掉","分隔符,報(bào)錯(cuò) */
if ( ! skipCh(','))
return error("Missing comma", lineNo,loc);
/* 第三寄存器操作數(shù)錯(cuò),非0-7之間數(shù)字,報(bào)錯(cuò) */
if ( (! getNum ()) || (num < 0) || (num >= NO_REGS) )
return error("Bad third register", lineNo,loc);
/* 將第三操作數(shù)arg3賦值為當(dāng)前數(shù)值num */
arg3 = num;
break;
/* 寄存器-內(nèi)存尋址模式 *
* 寄存器-立即數(shù)尋址模式 */
case opclRM :
case opclRA :
/* 第一寄存器操作數(shù)錯(cuò),非0-7之間數(shù)字,報(bào)錯(cuò) */
if ( (! getNum ()) || (num < 0) || (num >= NO_REGS) )
return error("Bad first register", lineNo,loc);
/* 將第一操作數(shù)arg1賦值為當(dāng)前數(shù)值num */
arg1 = num;
/* 第一操作數(shù)后面漏掉","分隔符,報(bào)錯(cuò) */
if ( ! skipCh(','))
return error("Missing comma", lineNo,loc);
/* 第二偏移地址操作數(shù)錯(cuò)誤,非數(shù)字偏移地址,報(bào)錯(cuò) */
if (! getNum ())
return error("Bad displacement", lineNo,loc);
/* 將第二偏移地址操作數(shù)arg2賦值為當(dāng)前地址num */
arg2 = num;
/* 第二偏移地址操作數(shù)后漏掉"(",或者是","分隔符,報(bào)錯(cuò) */
if ( ! skipCh('(') && ! skipCh(',') )
return error("Missing LParen", lineNo,loc);
/* 第二寄存器操作數(shù)錯(cuò),非0-7之間數(shù)字,報(bào)錯(cuò) */
if ( (! getNum ()) || (num < 0) || (num >= NO_REGS))
return error("Bad second register", lineNo,loc);
/* 將第三操作數(shù)arg3賦值為當(dāng)前數(shù)值num */
arg3 = num;
break;
}
/* 按代碼地址標(biāo)號(hào)loc將指令存儲(chǔ)到指令存儲(chǔ)區(qū)iMem */
iMem[loc].iop = op;
iMem[loc].iarg1 = arg1;
iMem[loc].iarg2 = arg2;
iMem[loc].iarg3 = arg3;
}
}
return TRUE;
} /* readInstructions */
/************************************************/
/* 函數(shù)名 stepTM */
/* 功 能 TM機(jī)單步執(zhí)行函數(shù) */
/* 說(shuō) 明 函數(shù)為一條指令解釋執(zhí)行,完成指令動(dòng)作. */
/************************************************/
STEPRESULT stepTM (void)
{
/* currentinstruction 用于存儲(chǔ)當(dāng)前將執(zhí)行的指令 */
INSTRUCTION currentinstruction ;
int pc ; /* 程序計(jì)數(shù)器 */
int r,s,t,m ; /* 指令操作數(shù) */
int ok ;
/* pc設(shè)置為第7個(gè)寄存器reg[7]的值,為程序計(jì)數(shù)器 */
pc = reg[PC_REG] ;
if ( (pc < 0) || (pc > IADDR_SIZE) )
/* pc的值不是指令存儲(chǔ)區(qū)的有效地址,報(bào)指令存儲(chǔ)錯(cuò),函數(shù)返回srIMEM_ERR */
return srIMEM_ERR ;
/* pc的值為有效指令地址,將程序計(jì)數(shù)器reg[PC_REG]的值加1 */
reg[PC_REG] = pc + 1 ;
/* 從指令存儲(chǔ)區(qū)iMem之中取出當(dāng)前指令 */
currentinstruction = iMem[ pc ] ;
/* 對(duì)取出的指令的尋址模式分類處理,初始化各個(gè)指令操作數(shù)變量 */
switch (opClass(currentinstruction.iop) )
{ case opclRR : /* 寄存器尋址模式 */
r = currentinstruction.iarg1 ;
s = currentinstruction.iarg2 ;
t = currentinstruction.iarg3 ;
break;
case opclRM : /* 寄存器-內(nèi)存尋址模式 */
r = currentinstruction.iarg1 ;
s = currentinstruction.iarg3 ;
m = currentinstruction.iarg2 + reg[s] ;
/* 操作數(shù)m非數(shù)據(jù)存儲(chǔ)區(qū)有效地址,報(bào)數(shù)據(jù)存儲(chǔ)錯(cuò),函數(shù)返回srDMEM_ERR */
if ( (m < 0) || (m > DADDR_SIZE))
return srDMEM_ERR ;
break;
case opclRA : /* 寄存器-立即數(shù)尋址模式 */
r = currentinstruction.iarg1 ;
s = currentinstruction.iarg3 ;
m = currentinstruction.iarg2 + reg[s] ;
break;
} /* case */
/* 對(duì)將執(zhí)行指令的操作碼值進(jìn)行分類處理,輸出指令信息, *
* 完成指令動(dòng)作,返回相應(yīng)結(jié)果狀態(tài) */
switch ( currentinstruction.iop)
{
/******************** RR指令 ******************/
/* 格式化屏幕顯示HALT(停止)指令,返回狀態(tài)srHALT(停止) */
case opHALT :
printf("HALT: %1d,%1d,%1d\n",r,s,t);
return srHALT ;
/**********************************************/
case opIN :
do
{
/* 屏幕顯示用戶提示信息,提示用戶為指令輸入數(shù)值 */
printf("Enter value for IN instruction: ") ;
/* 刷新標(biāo)準(zhǔn)輸入stdin流和標(biāo)準(zhǔn)輸出stdout流 */
fflush (stdin);
fflush (stdout);
/* 從標(biāo)準(zhǔn)輸入流stdin取得用戶輸入的數(shù)值,送入緩沖器in_Line */
gets(in_Line);
/* 取得用戶輸入數(shù)值的實(shí)際長(zhǎng)度lineLen */
lineLen = strlen(in_Line) ;
inCol = 0;
/* 如從緩沖器in_Line中成功取得數(shù)字,則ok為TRUE */
ok = getNum();
/* 用戶輸入的不是數(shù)字,報(bào)非法IN指令輸入錯(cuò)誤 */
if ( ! ok ) printf ("Illegal value\n");
/* 將輸入的數(shù)值num送入IN指令操作數(shù)r指定的寄存器reg[r] */
else reg[r] = num;
}
/* 如果用戶輸入不合法,重復(fù)要求用戶輸入,直到輸入合法數(shù)值 */
while (! ok);
break;
/**********************************************/
/* 屏幕顯示OUT指令執(zhí)行的結(jié)果信息 */
case opOUT :
printf ("OUT instruction prints: %d\n", reg[r] ) ;
break;
/**********************************************/
/* 完成ADD指令操作 */
case opADD : reg[r] = reg[s] + reg[t] ; break;
/**********************************************/
/* 完成SUB指令操作 */
case opSUB : reg[r] = reg[s] - reg[t] ; break;
/**********************************************/
/* 完成MUL指令操作 */
case opMUL : reg[r] = reg[s] * reg[t] ; break;
/**********************************************/
case opDIV :
/* 對(duì)于除法指令,若除數(shù)為0,則報(bào)除零錯(cuò)誤, *
* 并返回srZERODIVIDE;否則,完成除法操作 */
if ( reg[t] != 0 ) reg[r] = reg[s] / reg[t];
else return srZERODIVIDE ;
break;
/***************** RM 指令 ********************/
/* 將數(shù)據(jù)存儲(chǔ)區(qū)dMem中的數(shù)據(jù)載入到寄存器reg[r] */
case opLD : reg[r] = dMem[m] ; break;
/**********************************************/
/* 將寄存器reg[r]中的數(shù)據(jù)寫(xiě)入到數(shù)據(jù)存儲(chǔ)區(qū)dMem */
case opST : dMem[m] = reg[r] ; break;
/***************** RA 指令 ********************/
/* 將寄存器reg[r]賦值為操作數(shù)m的值 */
case opLDA : reg[r] = m ; break;
/**********************************************/
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -