⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tm.cpp

📁 snl语言是一个简单的具有嵌套过程定义的过程式语言
💻 CPP
📖 第 1 页 / 共 3 页
字号:

	/* 将寄存器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 + -