一、模型计算机及其仿真程序简介
模型机计算机[1],是一台为了让学生更容易理解计算机的工作原理而设计的一台虚构的计算机,它是一台功能简单而完备的计算机,它的字长8位,指令系统共有28条指令,存储器的最大容量是256字节。具有寄存器寻址、立即数寻址、直接寻址、变址、基址等5种寻址方式。能够实现输入/输出、中断等复杂的功能。
编写模型计算机仿真程序的目的,就是能够在Windows操作系统支持下仿真执行模型计算机汇编语言程序。从而可以帮助学生在PC计算机上完成模型计算机汇编语言程序的过程实验。
仿真程序的任务主要有两个,一个是要把用模型计算机汇编语言所编写的源程序转换成二进制的目标程序。二是要在Windows下仿真执行模型计算机的目标程序。输入的是源程序ASM文件,输出的是OBJ目标文件和LST列表文件。整个转换过程需要对源程序进行两遍扫描,第一遍扫描确定源程序的每一行的偏移地址,把程序中定义的变量、标识符的偏移地址记录下来存储在符号表中。第二遍扫描分析指令,伪指令等的操作数,产生OBJ目标文件和LST列表文件。
二、模型计算机汇编程序设计与实现
1.第一遍扫描的设计与实现
第一遍扫描是对模型计算机汇编语言源程序中的词法进行处理。包括指令的正确性分析,伪指令的数据分析,地址计数器值产生。然后把把程序中定义的变量、标识符的偏移地址记录下来存储在符号表中。同时在第一遍扫描时把每一条指令的指令助忆符,操作数等相关内容存储在代码表中,为了第二遍扫描时使用。具体过程如图1所示。
图1 第一遍扫描流程示意图
(1).地址计数器
地址计数器就是地址单元计数器。在对源程序开始第一遍扫描时,地址计数器初始化为零,在开始对源程序扫描时,每处理一条指令时,地址计数器就增加一个值,此值为该指令所需的字节数。所以,地址计数器可以看成是动态指向被扫描的源程序的相对位置的指针。也就是说地址计数器的内容即是当前正在被扫描的指令的偏移地址。对于指令和伪指令地址计数器的值产生有所不同。对伪指令ORG,地址计数器的值就重新设置成ORG所指示的值,表示从ORG所指示的地址开始计数。对DB或DS地址计数器的值就是地址计数器的当前值加上DB或DS后变量所占字节数,就是下一条指令的偏移地址。对于指令,地址计数器的值就是地址计数器的当前值加上指令的字节数,就是下一条指令的偏移地址。如此循环,直至第一遍扫描完成。
(2).符号表
在源程序中,用户可能定义常量、变量、标号等标识符,在第一遍扫描的过程中建立符号表,把用户定义的所有变量、标号标识符赋予当前地址计数器的值,对于常量只计算出表达式的值。
(3).机器指令表
机器指令表是一张固定的表格,列出所有的指令助忆符及其所对应的目标代码的信息,其中包括指令的目标代码、指令的屏蔽字、指令操作数说明以及指令的长度等。由于机器指令表信息不能改变,所以设计成常量数组,确保在程序执行时,不会由于错误引起对它进行任何改变。
(4).代码表
代码表设计成一个信息存储表,在第一遍扫描时,把每一条指令的指令助忆符、指令长度、变量或标号名、操作数个数及其类型,地址计数器的值等等信息保存在其中。在第二遍扫描时,不需要读取源程序文件,直接根据符号表、机器指令表和代码表把汇编语言指令翻译成目标代码,同时把指令目标代码和操作数的信息保存在代码表中,在执行界面上显示出来。
2、第二遍扫描的设计与实现
第二遍扫描是对模型计算机汇编语言源程序中的数据和语法进行处理,产生目标代码。对于伪指令分析数据格式,预留内存单元或在内存单元中产生相应的值。对于可执行指令分析它的指令和操作数,产生目标代码,并且设置内存单元。第二遍扫描完成后,如果没有错误,将生成列表文件和目标代码文件。
具体过程如图2所示。
(1).伪指令的数据分析
伪指令包括EQU、DB、DS、ORG的数据格式和数据值的分析。对于EQU可以使用表达式定义一个常量,如果EQU使用了表达式,表达式的某项由另一个EQU定义,则应该使用向后引用,即引用的某项必须先定义,然后才能引用。
对于DB在第一遍扫描时只计算出数据的长度,从而设置地址计数器,在第二遍扫描时需要计算出每个字节的具体数据值。对于不同类型的数据如:二进制、八进制、十六进制、字符串等表达式计算出具体的值。如果表达式的某项由另一个EQU定义,则也应该使用向后引用。
对于DS、ORG只要计算出操作数具体数据值设置地址计数器即可。
图2 第二遍扫描流程示意图
(2).执行指令及其操作数分析
如果判断这一条语句是执行指令的话,先查找这一条执行指令的目标代码,然后分析操作数。首先需要分析这一条指令的是否存在操作数,如果有操作数,分析该指令操作数的类型是:寄存器数、内存数、立即数之一。其次,分析该指令操作数的格式是否正确。最后计算操作数的值,和目标代码组合在一起,设置内存。并且计算和修改地址计数器的值。在对这一条执行指令分析过程中,把分析的结果信息同时也存入代码表中。
(3).向前引用问题
在汇编语句的操作数中可能出现变量或标号及其表达式,如果这个变量或标号已经在这条语句之前定义了,则称为向后引用。如果没有定义,则称为向前引用。一般情况下汇编程序在处理向前引用问题时都比较困难,因为指令的长度和操作数有关,操作数的类型不能确定,指令长度不能确定,就不能设置地址计数器的值,汇编就不能继续进行。这种情况下,假定操作数所占字节数是一个字节。在仿真程序中,第一遍扫描时,如果发现变量或标号,能够计算其值,那么计算出变量或标号的值,设置符号表。否则,不计算其值,地址计数器值修改是一样的。在第二遍扫描时计算出变量或标号的值,同时设置符号表中相关的变量或标号的值。
三、仿真执行部分的设计
模型计算机仿真程序,在对汇编源程序进行两次汇编后,产生了目标代码存储在OBJ文件之中,仿真程序可打开OBJ文件控制执行。仿真执行功能主要包括目标程序的连续执行、跟踪执行和单步执行。并且,能够设置断点和复位。连续执行就是从程序开始连续执行到结束或遇到断点为止。最后显示执行的结果。跟踪执行就是从程序开始连续执行到断点,用定时器控制每执行一条指令的停顿时间,然后继续执行,每一步都显示执行的结果。单步执行一次执行一条指令,每一步都显示执行的结果。 执行到断点就是在完整执行和跟踪执行时连续执行到此处停止,并且显示执行的结果。复位就是把程序恢复到未执行时的状态。
1.模型计算机硬件的模拟
我们知道程序在内存中执行,并在执行过程中对内存单元进行存取操作,而且需要使用寄存器、输入输出端口等。在仿真程序中,要用软件模拟出模型计算机的硬件环境。
模型计算机存储器的最大容量是256字节,仿真程序用数组模拟模型计算机存储器,具体地址00~FFH为I/O空间,用于输入输出端口地址,例如01H单元为基本数据输入端口,02H单元为基本数据输出端口等。地址10H~FFH为存储空间,用于存储代码或数据。
模型计算机的寄存器均为8位,其中,通用寄存器为AR、BR、IX和专用寄存器为SP、IR、PC、标志寄存器F。在仿真程序中分别用变量来模拟各个寄存器
2.目标程序仿真执行的过程
在模型计算机仿真程序中,我们对不同的汇编语言指令分别用不同的程序段来实现其功能。
目标程序仿真执行时,从代码表中查询到程序每一行的相应信息,如:指令目标代码、指令的操作数的类型、操作数的值等等。对不同的指令分别执行其对应的程序段,然后根据指令执行的结果设置堆栈、寄存器、内存单元等等。并且把堆栈、寄存器、内存单元和程序中定义的标识符的值都显示在仿真程序的界面之上,以便用户查看每条指令执行的结果。如果在执行指令时有中断请求,那么仿真程序会转到中断处理程序执行,执行完成后返回。如图3所示。
四、结束语
目前这个仿真程序作为《微型计算机原理与结构》这门课程的实验程序,在计算机实验室供学生学习使用。并在使用的过程中检测出程序存在的问题和功能上的不足,以便在下一个版本中改进。
参考文献
[1] 《微型计算机原理与结构》 张庆平著 清华大学出版社2006年
[2] 《IBM-PC汇编语言程序设计》 沈美明 温冬婵著 清华大学出版社 2004年
[3] 《编译原理与实践》 Kenneth C.Louden 著 冯博琴 冯岚 等译 机械工业出版社2000年