积木首页 | 500多种网页特效 | 函数手册 | 广播电台 | 高清晰图片素材 | 服务器合租 | 万年历 | 网友最新浏览记录
程序开发 网页设计 搜索引擎 特效代码 操作系统 防范病毒 黑客技术 图形图象 电脑硬件 网络技术 服 务 器 数 据 库 网文精粹
您的位置:积木首页 >> 黑客技术频道 >> 黑客编程 >> 正文:
标题:TM虚拟机源码
时间:2005-1-18 来源:不详 浏览数:
/****************************************************/
/* file: tm.c                                       */
/* The TM ("Tiny Machine") computer                 */
/* Compiler Construction: Principles and Practice   */
/* Kenneth C. Louden                                */
/****************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif

/******* const *******/
/* 只读指令存储区的大小 */
#define   IADDR_SIZE  1024 /* increase for large programs */
/* 数据区的大小 */
#define   DADDR_SIZE  1024 /* increase for large programs */
/* 寄存器的数目 */
#define   NO_REGS 8
/* PC寄存器(程序计数器)的下标 */
#define   PC_REG  7

#define   LINESIZE  121
#define   WORDSIZE  20

/******* type  *******/

/* 虚拟机的指令类型,有三种 */
typedef enum {
    opclRR,     /* reg operands r,s,t */
    opclRM,     /* reg r, mem d+s */
    opclRA      /* reg r, int d+s */
} OPCLASS;

/* 虚拟机的汇编指令对应的OPCODE */
typedef enum {
    /* RR instructions */
    opHALT,    /* RR     halt, operands are ignored */
    opIN,      /* RR     read into reg(r); s and t are ignored */
    opOUT,     /* RR     write from reg(r), s and t are ignored */
    opADD,     /* RR     reg(r) = reg(s)+reg(t) */
    opSUB,     /* RR     reg(r) = reg(s)-reg(t) */
    opMUL,     /* RR     reg(r) = reg(s)*reg(t) */
    opDIV,     /* RR     reg(r) = reg(s)/reg(t) */
    opRRLim,   /* limit of RR opcodes */

    /* RM instructions */
    opLD,      /* RM     reg(r) = mem(d+reg(s)) */
    opST,      /* RM     mem(d+reg(s)) = reg(r) */
    opRMLim,   /* Limit of RM opcodes */

    /* RA instructions */
    opLDA,     /* RA     reg(r) = d+reg(s) */
    opLDC,     /* RA     reg(r) = d ; reg(s) is ignored */
    opJLT,     /* RA     if reg(r)<0 then reg(7) = d+reg(s) */
    opJLE,     /* RA     if reg(r)<=0 then reg(7) = d+reg(s) */
    opJGT,     /* RA     if reg(r)>0 then reg(7) = d+reg(s) */
    opJGE,     /* RA     if reg(r)>=0 then reg(7) = d+reg(s) */
    opJEQ,     /* RA     if reg(r)==0 then reg(7) = d+reg(s) */
    opJNE,     /* RA     if reg(r)!=0 then reg(7) = d+reg(s) */
    opRALim    /* Limit of RA opcodes */
} OPCODE;

/* 枚举执行结果 */
typedef enum {
    srOKAY,               /* 正确执行 */
    srHALT,               /* 停止执行 */
    srIMEM_ERR,            /* IMEM错误 */
    srDMEM_ERR,            /* DMEM错误 */
    srZERODIVIDE            /* 零除错误 */
} STEPRESULT;

/* 存储指令的值,iop是OPCODE,剩下三个是r,s,t */
typedef struct {
    int iop;
    int iarg1;
    int iarg2;
    int iarg3;
} INSTRUCTION;

/******** vars ********/
/* 指向只读指令存储区的指针 */
int iloc = 0 ;
/* 指向数据存储区的指针 */
int dloc = 0 ;
/* 是否跟踪程序执行情况 */
int traceflag = FALSE;
/* 是否需要打印出执行的指令数量 */
int icountflag = FALSE;

/* 只读指令存储区 */
INSTRUCTION iMem [IADDR_SIZE];
/* 数据存储区 */
int dMem [DADDR_SIZE];
/* 寄存器 */
int reg [NO_REGS];

/* 指令列表,用于在stdout上打印出程序执行情况之用,与enum OPCODE对应,其中的"????"则与相应的LIM值对应,无意义 */
char *opCodeTab[] = {
    /* RR opcodes */
    "HALT","IN","OUT","ADD","SUB","MUL","DIV","????",
     /* RM opcodes */
    "LD","ST","????",
    /* RA opcodes */
    "LDA","LDC","JLT","JLE","JGT","JGE","JEQ","JNE","????"
};

/* 程序结果列表,用于在stdout上打印出程序执行情况之用,与enum STEPRESULT对应 */
char * stepResultTab[] =
{
    "OK",
    "Halted",
    "Instruction Memory Fault",
    "Data Memory Fault",
    "Division by 0"
};

/* 存储文件名 */
char pgmName[20];
/* 代码文件的FILE指针 */
FILE *pgm  ;

/* 文件的每一行都存在这个数组里 */
char in_Line[LINESIZE] ;
/* 读取到当前文件的行数记录 */
int lineLen;
/* in_Line数组中的下标 */
int inCol;
/* 存储getNum()函数的结果 */
int num  ;
/* 存储getWord()函数的结果 */
char word[WORDSIZE] ;
/* 存储getCh()函数的结果 */
char ch  ;
/* 存储docomand()函数的执行结果,用于表示程序是否结束 */
int done  ;

/*************************************************************************************
* int opClass( int c ):根据c的值在OPCODE枚举型中查找指令的类型,有RR,RM,RA三种指令
*************************************************************************************/
int opClass( int c )
{
    if ( c <= opRRLim)
        return ( opclRR );
    else if ( c <= opRMLim)
        return ( opclRM );
    else
        return ( opclRA );
} /* opClass */

/**************************************************************************************
*void writeInstruction ( int loc ):向stdout上打印出程序的执行情况
**************************************************************************************/
void writeInstruction ( int loc )
{
    printf( "%5d: ", loc) ;
    if ( (loc >= 0) && (loc < IADDR_SIZE) )
    {
        printf("%6s%3d,", opCodeTab[iMem[loc].iop], iMem[loc].iarg1);
        switch ( opClass(iMem[loc].iop) )
        {
        case opclRR:
            printf("%1d,%1d", iMem[loc].iarg2, iMem[loc].iarg3);
            break;
        case opclRM:
        case opclRA:
            printf("%3d(%1d)", iMem[loc].iarg2, iMem[loc].iarg3);
            break;
        }
        printf ("\n") ;
    }
} /* writeInstruction */

/*************************************************************************************
* void getCh (void):在in_line数组中读取字符,如果到文件尾,就返回空字符,并且将结果存入ch中
**************************************************************************************/
void getCh (void)
{
    if (++inCol < lineLen)
        ch = in_Line[inCol] ;
    else ch = ' ' ;
} /* getCh */

/**************************************************************************************
* int nonBlank (void): 查找某行文件后面是否都是空格,如果是则设置ch=' '并且返回false,
*                      否则设置ch为第一个非空字符返回true
***************************************************************************************/
int nonBlank (void)
{
    while ((inCol < lineLen)
         && (in_Line[inCol] == ' ') )
        inCol++ ;
    if (inCol < lineLen)
    {
        ch = in_Line[inCol] ;
        return TRUE ;
    }
    else
    {
        ch = ' ' ;
        return FALSE ;
    }
} /* nonBlank */

/***************************************************************************************
* int getNum (void):判断字符是否是数字,不是就返回false,否则返回true并且num中存储读入的数字
****************************************************************************************/
int getNum (void)
{
    int sign;
    int term;
    int temp = FALSE;
    num = 0 ;

    do {
        sign = 1;
        while ( nonBlank() && ((ch == '+') || (ch == '-')) )
        {
            temp = FALSE ;
            if (ch == '-') 
               sign = - sign ;
            getCh();
        }
        term = 0 ;
        nonBlank();
        while (isdigit(ch))
        {
            temp = TRUE ;
            term = term * 10 + ( ch - '0' ) ;
            getCh();
        }
        num = num + (term * sign) ;
    } while ( (nonBlank()) && ((ch == '+') || (ch == '-')) ) ;

    return temp;
} /* getNum */

/****************************************************************************************
*int getWord (void):判断后面紧接着的是否是符号,就是以字母或者数字开头的符号,是就返回true
*                   并且将该符号存入word数组之中,否则返回false
****************************************************************************************/
int getWord (void)
{
    int temp = FALSE;
    int length = 0;
    if (nonBlank ())
    {
        while (isalnum(ch))
        {
            if (length < WORDSIZE-1)
               word [length++] =  ch ;
            getCh() ;
        }
        word[length] = '\0';
        temp = (length != 0);
    }

    return temp;
} /* getWord */

/***************************************************************************************** 
*int skipCh ( char c  ):略过指定的字符,如果找不到这个字符那么返回false,否则返回true
*****************************************************************************************/
int skipCh ( char c  )
{
    int temp = FALSE;
    if ( nonBlank() && (ch == c) )
    {
        getCh();
        temp = TRUE;
    }
    return temp;
} /* skipCh */

/******************************************************************************************   
*int atEOL(void):是否到达行尾,是就返回非零值,否则返回零值
******************************************************************************************/
int atEOL(void)
{
    return ( ! nonBlank ());
} /* atEOL */

/*******************************************************************************************   
* int error( char * msg, int lineNo, int instNo):打印出错信息,其中msg是出错信息,
*                                                lineNo是行数,instNo是指令数
*******************************************************************************************/
int error( char * msg, int lineNo, int instNo)
{
    printf("Line %d",lineNo);
    if (instNo >= 0)
        printf(" (Instruction %d)",instNo);
    printf("   %s\n",msg);
    return FALSE;
} /* error */

/*******************************************************************************************   
* int readInstructions (void):读取代码文件进行处理
*******************************************************************************************/
int readInstructions (void)
{
    /* op存储指令 */
    OPCODE op;
    /* 存储r,s,t */
    int arg1, arg2, arg3;
    /* loc是指令的位置, regNO是寄存器的位置,lineNO是代码中的行数 */
    int loc, regNo, lineNo;

    /* 清空寄存器 */
    for (regNo = 0 ; regNo < NO_REGS ; regNo++)
        reg[regNo] = 0 ;
    /* 不明白为什么这样做? */
    dMem[0] = DADDR_SIZE - 1 ;
    /* 清空数据区 */
    for (loc = 1 ; loc < DADDR_SIZE ; loc++)
        dMem[loc] = 0 ;
    /* 初始化指令存储区的OPCODE是opHALT */
    for (loc = 0 ; loc < IADDR_SIZE ; loc++)
    {
        iMem[loc].iop = opHALT ;
        iMem[loc].iarg1 = 0 ;
        iMem[loc].iarg2 = 0 ;
        iMem[loc].iarg3 = 0 ;
    }
    /* 初始化行数为0 */
    lineNo = 0 ;
    while (! feof(pgm))      /* 对文件进行逐行的读取操作,然后对每一行代码进行处理 */
    {
        /* 读入一行代码 */
        fgets( in_Line, LINESIZE-2, pgm  ) ;
        /* 设置行的列号为0 */
        inCol = 0 ;
        /* 行数加一 */
        lineNo++;
        lineLen = strlen(in_Line)-1 ;
        /* 把行尾置为'\0',方便字符串操作 */
        if (in_Line[lineLen]=='\n')
            in_Line[lineLen] = '\0' ;
        else
            in_Line[++lineLen] = '\0';
        /* 如果指令不是空格或者注释 */
        if ( (nonBlank()) && (in_Line[inCol] != '*') )
        {
            /* 如果不是数字,就显示错误,因为指令都是以数字开始 */
            if (! getNum())
               return error("Bad location", lineNo,-1);
            /* 存储指令的位置 */
            loc = num;
            /* 大于指令存储区的大小 */
            if (loc > IADDR_SIZE)
               return error("Location too large",lineNo,loc);
            /* 如果后面没有紧接着':',则显示出错 */
            if (! skipCh(':'))
               return error("Missing colon", lineNo,loc);
            /* 如果后面紧接着的不是符号,则显示出错 */
            if (! getWord ())
               return error("Missing opcode", lineNo,loc);
            /* 初始化为HALT指令 */
            op = opHALT ;
            /* 循环查找word指令对应的OPCODE,op就是在opCodeTab中对应的指令的下标 */
            while ((op < opRALim)
                 && (strncmp(opCodeTab[op], word, 4) != 0) )
               op++ ;
            /* 没有找到对应的OPCODE,显示出错 */
            if (strncmp(opCodeTab[op], word, 4) != 0)
               return error("Illegal opcode", lineNo,loc);
            
            /* 调用opClass函数对指令进行分类,不同的指令处理不相同 */
            switch ( opClass(op) )
            {
            case opclRR :   /* 处理RR指令,具体为什么会如下处理可以查看RR指令的格式 */
               /* 如果后面紧接着的不是数字或者数字是非法的就显示出错 */
               if ( (! getNum ()) || (num < 0) || (num >= NO_REGS) )
                   return error("Bad first register", lineNo,loc);
               arg1 = num;
               /* 如果后面没有紧跟着',',就显示出错 */
               if ( ! skipCh(','))
                   return error("Missing comma", lineNo, loc);
                    /* 如果后面紧接着的不是数字或者数字是非法的就显示出错 */
               if ( (! getNum ()) || (num < 0) || (num >= NO_REGS) )
                   return error("Bad second register", lineNo, loc);
               arg2 = num;
               /* 如果后面没有紧跟着',',就显示出错 */
               if ( ! skipCh(','))
                   return error("Missing comma", lineNo,loc);
               /* 如果后面紧接着的不是数字或者数字对于RR命令是非法的就显示出错 */
               if ( (! getNum ()) || (num < 0) || (num >= NO_REGS) )
                   return error("Bad third register", lineNo,loc);
               arg3 = num;
               break;

            case opclRM :   /* 处理RM指令,具体为什么会如下处理可以查看RM指令的格式 */
            case opclRA :   /* 处理RA指令,具体为什么会如下处理可以查看RA指令的格式 */
               /* 如果后面紧接着的不是数字或者数字是非法的就显示出错 */
               if ( (! getNum ()) || (num < 0) || (num >= NO_REGS) )
                   return error("Bad first register", lineNo,loc);
               arg1 = num;
               /* 如果后面没有紧跟着','就显示出错 */
               if ( ! skipCh(','))
                   return error("Missing comma", lineNo,loc);
               /* 如果后面没有紧跟着数字就显示出错 */
               if (! getNum ())
                   return error("Bad displacement", lineNo,loc);
               arg2 = num;
               /* 如果后面没有紧跟着'('或者是','就显示出错 */
               if ( ! skipCh('(') && ! skipCh(',') )
                   return error("Missing LParen", lineNo,loc);
               /* 如果紧跟的不是数字或者数字是非法的就显示出错 */
               if ( (! getNum ()) || (num < 0) || (num >= NO_REGS))
                   return error("Bad second register", lineNo,loc);
               arg3 = num;
               break;
            } /* switch ( opClass(op) ) */
            /* OK,读取一行代码结束,把指令存入指令存储区 */
            iMem[loc].iop = op;
            iMem[loc].iarg1 = arg1;
            iMem[loc].iarg2 = arg2;
            iMem[loc].iarg3 = arg3;
        }   /* if ( (nonBlank()) && (in_Line[inCol] != '*') ) */
    }      /* while (! feof(pgm)) */

    return TRUE;
} /* readInstructions */

/********************************************************************************************
* STEPRESULT stepTM (void):根据指令内存区中的存储的指令逐步执行指令,并且返回执行结果
********************************************************************************************/
STEPRESULT stepTM (void)
{
    INSTRUCTION currentinstruction  ;
    int pc  ;
    int r,s,t,m  ;
    int ok ;

    /* 从PC寄存器中读取下一条指令地址 */
    pc = reg[PC_REG] ;
    /* 如果小于零或者大于IADDR_SIZE,就是超过指令内存大小,就返回srIMEM_ERR错误 */
    if ( (pc < 0) || (pc > IADDR_SIZE)  )
        return srIMEM_ERR ;
    /* PC加一 */
    reg[PC_REG] = pc + 1 ;
    /* 从内存中根据PC地址值读取当前要执行的指令 */
    currentinstruction = iMem[ pc ] ;
   
     /*  调用opClass函数确定opcode的类型 */
    switch (opClass(currentinstruction.iop) )
    {
    case opclRR :            /* 对于RR指令而言,opcode格式是opcode r, s, t */
        r = currentinstruction.iarg1 ;
        s = currentinstruction.iarg2 ;
        t = currentinstruction.iarg3 ;
        break;
       
    case opclRM :             /* 对于RM指令而言,opcode格式是opcode r, d(s),而m = d + reg(s) */
        r = currentinstruction.iarg1 ;
        s = currentinstruction.iarg3 ;
        /* 对应RM指令中的m = d + reg[s],相当于变址寻址,这个地址用于访问数据区 */
        m = currentinstruction.iarg2 + reg[s] ;
        /* 如果地址是非法的(对于数据存储区而言),就返回一个srDMEM_ERR错误 */
        if ( (m < 0) || (m > DADDR_SIZE))
            return srDMEM_ERR ;
        break;

    case opclRA :            /* 对于RA指令而言,opcode格式是opcode r, d(s),而m = d + reg(s),m值最后存入相应的寄存器 */
        r = currentinstruction.iarg1 ;
        s = currentinstruction.iarg3 ;
        m = currentinstruction.iarg2 + reg[s] ;
        break;
    } /* case */

    /* 根据iop中存储的OPCODE来执行指令,每个case右边是指令的执行情况 */
    switch ( currentinstruction.iop)
    {
    case opHALT :            /* RR     halt, operands are ignored */
        printf("HALT: %1d,%1d,%1d\n",r,s,t);
        return srHALT ;
        /* break; */

    case opIN :            /* RR     read into reg(r); s and t are ignored */
        do{
            printf("Enter value for IN instruction: ") ;
            fflush (stdin);
            fflush (stdout);
            gets(in_Line);
            lineLen = strlen(in_Line) ;
            inCol = 0;
            ok = getNum();
            if ( ! ok )
               printf ("Illegal value\n");
            else
               reg[r] = num;
        } while (! ok);
        break;

    case opOUT :              /* RR     write from reg(r), s and t are ignored */
        printf ("OUT instruction prints: %d\n", reg[r] ) ;
        break;
    case opADD :              /* RR     reg(r) = reg(s)+reg(t) */
        reg[r] = reg[s] + reg[t] ; 
        break;
    case opSUB :              /* RR     reg(r) = reg(s)-reg(t) */
        reg[r] = reg[s] - reg[t] ; 
        break;
    case opMUL :              /* RR     reg(r) = reg(s)*reg(t) */
        reg[r] = reg[s] * reg[t] ; 
        break;

    case opDIV :            /* RR     reg(r) = reg(s)/reg(t) */
        if ( reg[t] != 0 )
            reg[r] = reg[s] / reg[t];
        else
            return srZERODIVIDE ;
        break;

     /*************** RM instructions ********************/
    case opLD :             /* RM     reg(r) = mem(d+reg(s)) */
        reg[r] = dMem[m] ; 
        break;
    case opST :             /* RM     mem(d+reg(s)) = reg(r) */
        dMem[m] = reg[r] ; 
        break;

    /*************** RA instructions ********************/
    case opLDA :             /* RA     reg(r) = d+reg(s) */
        reg[r] = m ;
        break;
    case opLDC :             /* RA     reg(r) = d ; reg(s) is ignored */
        reg[r] = currentinstruction.iarg2 ;   
        break;
    case opJLT :             /* RA     if reg(r)<0 then reg(7) = d+reg(s) */
        if ( reg[r] <  0 )
            reg[PC_REG] = m ;
        break;
    case opJLE :             /* RA     if reg(r)<=0 then reg(7) = d+reg(s) */
        if ( reg[r] <=  0 )
            reg[PC_REG] = m ;
        break;
    case opJGT :             /* RA     if reg(r)>0 then reg(7) = d+reg(s) */
        if ( reg[r] >  0 )
            reg[PC_REG] = m ;
        break;
    case opJGE :             /* RA     if reg(r)>=0 then reg(7) = d+reg(s) */
        if ( reg[r] >=  0 )
            reg[PC_REG] = m ;
        break;
    case opJEQ :             /* RA     if reg(r)==0 then reg(7) = d+reg(s) */
        if ( reg[r] == 0 )
            reg[PC_REG] = m ;
        break;
    case opJNE :             /* RA     if reg(r)!=0 then reg(7) = d+reg(s) */
        if ( reg[r] != 0 )
            reg[PC_REG] = m ;
        break;

        /* end of legal instructions */
    } /* case */
   
     /* 如果程序能够正常执行到这里,就返回执行正确的信息 */
    return srOKAY ;
} /* stepTM */

/********************************************************************************************
*int doCommand (void):执行指令
* *******************************************************************************************/
int doCommand (void)
{
    char cmd;
    int stepcnt=0, i;
    int printcnt;
    int stepResult;
    int regNo, loc;

    do {                   /* 读入执行虚拟机的命令行参数 */
        printf ("Enter command: ");
        fflush (stdin);
        fflush (stdout);
        gets(in_Line);
        lineLen = strlen(in_Line);
        inCol = 0;
    } while (! getWord ());

    cmd = word[0] ;
    switch ( cmd )
    {
    case 't' :               /* 是否跟踪调试 */
        traceflag = ! traceflag ;
        printf("Tracing now ");
        if ( traceflag )
            printf("on.\n");
        else
            printf("off.\n");
        break;

    case 'h' :               /* 打印出命令及相应功能列表 */
        printf("Commands are:\n");
        printf("   s(tep <n>      "\
             "Execute n (default 1) TM instructions\n");
        printf("   g(o            "\
             "Execute TM instructions until HALT\n");
        printf("   r(egs          "\
             "Print the contents of the registers\n");
        printf("   i(Mem <b <n>>  "\
             "Print n iMem locations starting at b\n");
        printf("   d(Mem <b <n>>  "\
             "Print n dMem locations starting at b\n");
        printf("   t(race         "\
             "Toggle instruction trace\n");
        printf("   p(rint         "\
             "Toggle print of total instructions executed"\
             " ('go' only)\n");
        printf("   c(lear         "\
             "Reset simulator for new execution of program\n");
        printf("   h(elp          "\
             "Cause this list of commands to be printed\n");
        printf("   q(uit          "\
             "Terminate the simulation\n");
        break;

    case 'p' :               /* 是否打印出执行的指令的步数 */
        icountflag = ! icountflag ;
        printf("Printing instruction count now ");
        if ( icountflag )
            printf("on.\n");
        else
            printf("off.\n");
        break;

    case 's' :               /* 指定执行的步数 */
        if ( atEOL ()) 
            stepcnt = 1;
        else if ( getNum ()) 
            stepcnt = abs(num);
        else
            printf("Step count?\n");
        break;

    case 'g' :               /* 执行指令一直到HALT */
        stepcnt = 1 ;     
        break;

    case 'r' :               /* 打印出寄存器中的内容 */
        for (i = 0; i < NO_REGS; i++)
        {
            printf("%1d: %4d    ", i,reg[i]);
            if ( (i % 4) == 3 )
               printf ("\n");
        }
        break;

    case 'i' :               /* 打印出只读指令存储区的内容(指令),也可以自己指定存储区的位置 */
        printcnt = 1 ;
        /* printcnt用于计数,计算总共要打印出多少行的内容,而iloc是指向这一段内存的指针 */
        if ( getNum ())
        {
            iloc = num ;
            if ( getNum ())
               printcnt = num ;
        }
        if ( ! atEOL ())
            printf ("Instruction locations?\n");
        else
        {
            while ((iloc >= 0) && (iloc < IADDR_SIZE)
                 && (printcnt > 0) )
            {
               writeInstruction(iloc);
               iloc++ ;
               printcnt-- ;
            }
        }
        break;

    case 'd' :               /* 打印出数据存储区的内容(指令),也可以自己指定存储区的位置 */
        printcnt = 1 ;
        /* printcnt用于计数,计算总共要打印出多少行的内容,而dloc是指向这一段内存的指针 */
        if ( getNum  ())
        {
            dloc = num ;
            if ( getNum ())
               printcnt = num ;
        }
        if ( ! atEOL ())      
            printf("Data locations?\n");
        else
        {
            while ((dloc >= 0) && (dloc < DADDR_SIZE)
                 && (printcnt > 0))
            {
               printf("%5d: %5d\n",dloc,dMem[dloc]);
               dloc++;
               printcnt--;
            }
        }
        break;

    case 'c' :               /* 清空虚拟机所有状态 */
        iloc = 0;
        dloc = 0;
        stepcnt = 0;
        for (regNo = 0;  regNo < NO_REGS ; regNo++)
            reg[regNo] = 0 ;
        dMem[0] = DADDR_SIZE - 1 ;
        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;
    if ( stepcnt > 0 )
    {
        if ( cmd == 'g' )
        {
            stepcnt = 0;
            /* 当命令行参数是g的时候,就一直执行程序 */
            while (stepResult == srOKAY)
            {
               iloc = reg[PC_REG] ;
               /* 如果设置了跟踪标志,那么在stdout上打印出执行的指令 */
               if ( traceflag )
                   writeInstruction( iloc ) ;
               stepResult = stepTM ();
               stepcnt++;
            }
            /* 打印出执行的指令数量 */
            if ( icountflag )
               printf("Number of instructions executed = %d\n",stepcnt);
        }
        else               /* 否则根据stepResult中指定的步长执行指令 */
        {
            while ((stepcnt > 0) && (stepResult == srOKAY))
            {
               iloc = reg[PC_REG] ;
               if ( traceflag )
                   writeInstruction( iloc ) ;
               stepResult = stepTM ();
               stepcnt-- ;
            }
        }
        printf( "%s\n",stepResultTab[stepResult] );
    }
    return TRUE;
} /* doCommand */

/********************************************************************************************
*int main( int argc, char * argv[] ):主函数
********************************************************************************************/
int main( int argc, char * argv[] )
{
    if (argc != 2)
    { printf("usage: %s <filename>\n",argv[0]);
        exit(1);
    }
    strcpy(pgmName,argv[1]) ;
    if (strchr (pgmName, '.') == NULL)
        strcat(pgmName,".tm");
    pgm = fopen(pgmName,"r");
    if (pgm == NULL)
    { printf("file '%s' not found\n",pgmName);
        exit(1);
    }

    /* read the program */
    if ( ! readInstructions ())
        exit(1) ;
    /* switch input file to terminal */
    /* reset( input ); */
    /* read-eval-print */
    printf("TM  simulation (enter h for help)...\n");
    do
        done = ! doCommand ();
    while (! done );
    printf("Simulation done.\n");

    return 0;
}

(责任编辑:欣欣裴)
关于本站 | 广告服务 | 联系我们 | 版权申明 | 强强联盟 | 投稿热线 | 网站地图 | 申请链接
Copyright ©2005-2006 Gimoo.net All rights reserved. 积木网 版权所有
E-mail:gimoohr@gmail.com 京ICP备05050695号