欢迎来到装配图网! | 帮助中心 装配图网zhuangpeitu.com!
装配图网
ImageVerifierCode 换一换
首页 装配图网 > 资源分类 > DOC文档下载
 

C语言课程设计模拟器和汇编程序的设计

  • 资源ID:144839062       资源大小:269.50KB        全文页数:55页
  • 资源格式: DOC        下载积分:10积分
快捷下载 游客一键下载
会员登录下载
微信登录下载
三方登录下载: 微信开放平台登录 支付宝登录   QQ登录   微博登录  
二维码
微信扫一扫登录
下载资源需要10积分
邮箱/手机:
温馨提示:
用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
支付方式: 支付宝    微信支付   
验证码:   换一换

 
账号:
密码:
验证码:   换一换
  忘记密码?
    
友情提示
2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

C语言课程设计模拟器和汇编程序的设计

华中科技大学计算机科学与技术学院C语言课程设计报告 题目:模拟器和汇编程序的设计专 业:计算机科学与技术班 级:学 号:姓 名:成 绩:指导教师:李开完成日期: 2012年 10 月 15 日目 录一、系统需求分析1二、总体设计6三、数据结构设计7四、详细设计9五、系统实现13六、运行测试与结果分析42七、总结44八、参考文献45九、指导教师评语46一、系统需求分析Simulator and Assembler1. 用C语言编制汇编程序,将此简单计算机的汇编源程序翻译成目标代码,即机器码。为了测试所编制汇编程序的正确性,需用以上介绍的指令集编写两个汇编源程序,汇编源程序的功能要求为: 求1+2+3+100,并输出运算结果。 求将” Simulator and Assembler”拷贝复制到新串并输出运算结果。串并输出运算结果。其中,32条指令以及伪指令和它们的功能如下:(1) 停机指令:HLT功能:终止程序运行。(2) 无条件转移指令:JMP label功能:将控制转移至标号label处,执行标号label后的指令。(3) 比较运算转移指令:CJMP label功能:如果程序状态字中比较标志位c的值为1(即关系运算的结果为真),则将控制转移至标号label处,执行标号label后的指令;否则,顺序往下执行。(4) 溢出转移指令:OJMP功能:如果程序状态字中比较标志位o的值为1(即算术运算的结果发生溢出),则将控制转移至标号label处,执行标号label后的指令;否则,顺序往下执行。(5) 调用子程序指令:CALL label功能:将通用寄存器AG、程序状态字PSW、程序计数器PC中的值保存到ES,然后调用以标号label开始的子程序,将控制转移至标号label处,执行标号label后的指令。(6) 子程序返回指令:RET功能:将ES中保存的通用寄存器AZ、程序状态字PSW和程序字数器PC的值恢复,控制转移到子程序被调用的地方,执行调用指令的下一条指令。(7) 入栈指令:PUSH reg0功能:将通用寄存器reg0的值压入堆栈SS,reg0可以是AG和Z八个通用寄存器之一。(8) 出栈指令:POP reg0功能:从堆栈SS中将数据出栈到寄存器reg0,reg0可以是AG七个通用寄存器之一,但不能是通用寄存器Z。(9) 取字节数据指令:LOADB reg0 symbol功能:从字节数据或字节数据块symbol中取一个字节的数据存入寄存器reg0,所取的字节数据在数据块symbol中的位置由寄存器G的值决定。用C的语法可将此指令的功能描述为: reg0 = symbolG例如,假设用伪指令定义了以下字节数据块num: BYTE num10 = 5,3,2,8,6,9,1,7,4,0如果要将字节数据块num中第5个单元的值(即下标为4的元素)取到寄存器C,指令如下: LOADI G 5 LOADB C num后面的指令LOADW、STOREB和STOREW在操作上与此指令类似。(10) 取双字节数据指令:LOADW reg0 symbol功能:从双字节数据或双字节数据块symbol中取一个双字节的数据存入寄存器reg0,所取的双字节数据在数据块symbol中的位置由寄存器G的值决定。(11) 存字节数据指令:STOREB reg0 symbol功能:将寄存器reg0的值存入字节数据或字节数据块symbol中的某个单元,存入单元的位置由寄存器G的值决定。用C的语法可将此指令的功能描述为: symbolG = reg0(12) 存双字节数据指令:STOREW reg0 symbol功能:将寄存器reg0的值存入双字节数据或双字节数据块symbol中的某个单元,存入单元的位置由寄存器G的值决定。(13) 取立即数指令:LOADI reg0 immediate功能:将指令中的立即数immediate存入寄存器reg0。立即数被当作16位有符号数,超出16位的高位部分被截掉。例如: LOADI B 65535寄存器B的值为-1。 LOADI B 65537寄存器B的值为1。(14) 空操作指令:NOP功能:不执行任何操作,但耗用一个指令执行周期。(15) 控制台输入指令:IN reg0 0功能:从输入端口(即键盘输入缓冲区)取一个字符数据,存入寄存器reg0。(16) 控制台输出指令:OUT reg0 15功能:将寄存器reg0的低字节作为字符数据输出到输出端口(即显示器)。(17) 加运算指令:ADD reg0 reg1 reg2功能:将寄存器reg1的值加上reg2的值,结果存入寄存器reg0。如果结果超过16位有符号数的表示范围,将发生溢出,使程序状态字的溢出标志位o置为1;如果未发生溢出,则使程序状态字的溢出标志位o置为0。(18) 加立即数指令:ADDI reg0 immediate功能:将寄存器reg0的值加上立即数immediate,结果仍存入寄存器reg0。如果结果超过16位有符号数的表示范围,将发生溢出,使程序状态字的溢出标志位o置为1;如果未发生溢出,则使程序状态字的溢出标志位o置为0。(19) 减运算指令:SUB reg0 reg1 reg2功能:将寄存器reg1的值减去reg2的值,结果存入寄存器reg0。如果结果超过16位有符号数的表示范围,将发生溢出,使程序状态字的溢出标志位o置为1;如果未发生溢出,则使程序状态字的溢出标志位o置为0。(20) 减立即数指令:SUBI reg0 immediate功能:将寄存器reg0的值减去立即数immediate,结果仍存入寄存器reg0。如果结果超过16位有符号数的表示范围,将发生溢出,使程序状态字的溢出标志位o置为1;如果未发生溢出,则使程序状态字的溢出标志位o置为0。(21) 乘运算指令:MUL reg0 reg1 reg2功能:将寄存器reg1的值乘以reg2的值,结果存入寄存器reg0。如果结果超过16位有符号数的表示范围,将发生溢出,使程序状态字的溢出标志位o置为1;如果未发生溢出,则使程序状态字的溢出标志位o置为0。(22) 除运算指令:DIV reg0 reg1 reg2功能:将寄存器reg1的值除以reg2的值,结果存入寄存器reg0,这里进行的是整数除运算。如果寄存器reg2的值为零,将发生除零错。(23) 按位与运算指令:AND reg0 reg1 reg2功能:将寄存器reg1的值与reg2的值进行按位与运算,结果存入寄存器reg0。(24) 按位或运算指令:OR reg0 reg1 reg2功能:将寄存器reg1的值与reg2的值进行按位或运算,结果存入寄存器reg0。(25) 按位异或运算指令:NOR reg0 reg1 reg2功能:将寄存器reg1的值与reg2的值进行按位异或(按位加)运算,结果存入寄存器reg0。(26) 按位取反运算指令:NOTB reg0 reg1功能:将寄存器reg1的值按位取反后,结果存入寄存器reg0。(27) 算术左移运算指令:SAL reg0 reg1 reg2功能:将寄存器reg1的值算术左移reg2位,结果存入寄存器reg0。在进行算术左移时,低位空位用0填充。(28) 算术右移运算指令:SAR reg0 reg1 reg2功能:将寄存器reg1的值算术右移reg2位,结果存入寄存器reg0。在进行算术右移时,高位空位用符号位填充。(29) 相等关系运算指令:EQU reg0 reg1功能:将两个寄存器reg0和reg1的值进行相等比较关系运算:reg0 = reg1,关系运算的结果为逻辑真或逻辑假,存入程序状态字中的比较标志位c。(30) 小于关系运算指令:LT reg0 reg1功能:将两个寄存器reg0和reg1的值进行小于关系运算:reg0 < reg1,关系运算的结果为逻辑真或逻辑假,存入程序状态字中的比较标志位c。(31) 小于等于关系运算指令:LTE reg0 reg1功能:将两个寄存器reg0和reg1的值进行小于等于关系运算:reg0 <= reg1,关系运算的结果为逻辑真或逻辑假,存入程序状态字中的比较标志位c。(32) 比较标志位取反指令:NOTC功能:将程序状态字中的比较标志位c求反,即将逻辑真变为逻辑假,将逻辑假变为逻辑真。(33) 字节数据定义伪指令:BYTE symboln = . 蓝色字体部分为可选项 或:BYTE symboln = "." 蓝色字体部分为可选项功能:定义长度为1字节的字节型数据或数据块,字节型数据块类似于C的字符数组。(34) 字数据定义伪指令:WORD symboln = . 蓝色字体部分为可选项功能:定义长度为2字节的双字节型数据或数据块,双字节型数据块类似于C的整型数组(16位系统)。2. 用C语言编制一个模拟器,能够模拟此简单计算机执行汇编程序生成的目标代码,得到运行结果。注:编写好编译程序和模拟器后,再用八皇后程序检验。二、总体设计模拟器和汇编程序设计(1) 编译程序编译程序从汇编语言源文件中第一行开始,每次取一条指令,对其进行解析并翻译成十六进制的目标代码,存入目标文件,直到源文件结束。用循环反复处理从源文件输入的每一行指令,直到遇到文件尾时终止循环;用函数fgets从源文件读入一行字符串,存入字符数组a_line。对注释的处理:用函数strchr查找a_line中字符 '#' 首次出现的位置,如果找到则用空字符'0' 来替换。用此方法去掉指令尾部的注释。对标号的处理:建立一个链表来存储标号的位置,名称等信息,第一遍扫描源程序时,用函数strchr查找a_line中字符 ':' 出现的位置,将标号的名称和位置存入链表中,在翻译目标代码时,再计算标号的偏移量。对伪指令的处理:建立一个存储伪指令定义的标识符的类型,名称,长度,数据等信息的链表,第一遍扫描源程序时,将伪指令的信息存入链表中。翻译目标代码时,将伪指令定义的变量值放在所有目标代码的后面。(2) 模拟器模拟器对该简单计算机的处理器、内存和终端设备进行模拟。当模拟器运行时,首先将经汇编程序汇编后的目标程序读入到内存,然后模拟目标程序的运行,直到执行HLT指令时终止。用一个无符号字符类型的数组来模拟内存;目标文件中每行存放一条十六进制的指令代码,依次将每行指令代码读入到模拟内存中;8个通用寄存器AG和Z用unsigned short数组来模拟;处理器可用“取指解码执行”循环来模拟。三、数据结构设计(1) 编译程序编译程序中,用先进先出链表来存放标号和伪指令的有关数据,具体如下图:H标号2信息标号1信息标号3信息标号4信息 存放伪指令定义的标识符的链表大致如上当扫描汇编源程序时,处理标号和伪指令,此时建立链表并存储信息。在调用计算标号的偏移量和输出伪指令定义的变量值时,再遍历链表。(2) 模拟器模拟器中,内存的结构大致如下其中,CS是代码段,DS是数据段,SS是堆栈段,ES是附加段,Port是两个终端设备控制台。代码段用无符号长整型数组模拟,数据段用无符号字符型数组模拟,堆栈段用短整型数组模拟,而附加段用存放若干个结构体指针的数组来模拟,这里的结构体中存放了指令计数器PC、程序状态字PSW和通用寄存器。加载目标代码时,指令计数器PC指向内存的顶端,依次将指令加载到模拟内存。加载完后,将PC指向堆栈段SS,然后将伪指令定义的变量存入数据段,数据段DS紧接着数据段CS,SS紧挨着DS,而将ES放到内存的底部。因此SS和ES进出的方向是相反的。下面简要说一下堆栈段和附加段的用法:在CALL指令调用并执行子程序,控制将转移到子程序,子程序的地址由标号给出。如果调用子程序前需要向子程序传递参数(类似于函数的参数),可用PUSH指令将参数压入堆栈,子程序中用POP指令取出参数,注意堆栈是先进后出。参数是通过堆栈段传递的。更重要的是,在将控制转移到子程序前,CALL指令要将相关寄存器(主要是指令计数器PC、程序状态字PSW和通用寄存器)的内容保存起来,因为子程序也要用这些寄存器存放指令或数据。这些寄存器的值保存在附加段中,附加段的使用类似于堆栈段,但他们存放数据的方向不一样,堆栈段数据进栈时,栈顶向高地址方向增加,出栈则向低地址方向减小;附加段栈顶的变化正好与堆栈段的栈顶相反,堆栈段SS和附加段ES共用一块内存区,这样设计的理由是提高内存的利用率。当子程序执行到RET指令时,控制要返回到先前CALL指令的下一条指令接着执行,从附加段中把保存的相关寄存器的值恢复到原寄存器即可。四、 详细设计1. 编译程序编译程序从汇编语言源文件中第一行开始,每次取一条指令,对其进行解析并翻译成十六进制的目标代码,存入目标文件,直到源文件结束。用循环反复处理从源文件输入的每一行指令,直到遇到文件尾时终止循环;用函数fgets从源文件读入一行字符串,存入字符数组a_line。用函数sscanf从数组a_line中输入一个字符串到字符数组op_sym并将函数返回值赋给n。如果n为0,哪么数组a_line中存放的是空行或注释行,直接取下一行再接着进行处理。如果n不为0,那么读入数组op_sym中的字符串就是该指令的助记符,由此可知该指令的格式。接下来再次用函数sscanf从数组a_line中输入字符串到以下4个字符数组op_sym,reg0,reg1和reg2,分别判断reg0,reg1和reg2中的字符串,并依次给对应的整型变量arg0,arg1和arg2赋值。在此之前,用宏指令将每个指定助记符都定义成符号常量,以表示指令助记符对应的指令操作码;同样,将各条指令转换成目标代码的算法定义成带参的宏。再用函数fgets从源文件读入下一行字符串,进行下一轮循环处理。下面是编译程序的流程图:开始Y4文件是否到结尾?(第一次扫描源程序)NY读入一行字符串是变量?NNY是标号?231 12将变量信息存入链表将标号信息存入链表3行数加14关闭文件并重新打开Y文件是否到结尾?(第二次扫描源程序)N是注释?读入一行字符串NY用空字符替换Y结束循环是变量?NN将伪指令所定义的变量的值放在所有目标代码的后面是标号?Y行数加1将标号后的字符串存入数组op_sym中结束翻译成目标代码2. 模拟器由于每条指令的长度是4个字节,所以将程序计数器PC定义成无符号长整型指针,这样,一次可以取到一条完整的指令,同时程序计数器的值加1就可以指向下一条指令。在将指令代码读到模拟内存时,先用fscanf函数从目标文件中读取一条指令代码到一个unsigned long类型的临时变量,然后用memcpy函数将该临时变量的内容复制到模拟内存中。处理器在执行时,从程序计数器PC指示的内存单元将指令载入到指令寄存器IR,然后将PC的值增加1,使其指向下一条指令,为下一轮循环做准备。接下来对指令进行解码。另外,将寄存器编号、立即数、数据在内存中的地址定义成宏。其中,指令操作码opcode可通过按位右移得到:OPCODE = (IR >> 27) & 0x0F;通用寄存器用unsigned short数组来模拟;每条指令的功能用一个无参整型函数来实现,再定义一个函数指针数组ops,将32个函数的入口地址保存到数组ops中,数组下标与函数所对应指令操作码一致,这样,从指令中解码得到指令操作码后,就可以用如下表达式调用指令功能的实现函数,模拟指令的执行。(*opsOPCODE)();接下来进行下一轮循环,直到执行函数HLT退出循环。下面是模拟器程序的流程图:开始 SS = (short *)PC; PC-; DS = (char *)PC - *PC; ES = (struct Extra *)(MEM + mem_size - sizeof(struct Extra);打开文件Y文件到结尾?N关闭文件取出代码PC指向第一条指令加载到内存PC+;CS = PC;N函数返回值为1?Y取指:将PC指示的指令加载到指令寄存器IRPC指向下一条执行指令解码并执行指令令结束五、系统实现两个汇编程序源码:累加: #1加到100LOADIA100# 循环的上界设为100LOADIB1# 将循环次数存入寄存器B中LOADIC0# 将和数存入寄存器C中LOADID10# 用于转换时的除数LOADIE1000# 将和数转换成字符的除数LOADIF0# 用于提取个位,十位等的数字LOADIG0# 用于转换时的减数loop:ADDCCB# 计算D = C + BADDIB1# 将B的值增加1LTEBA# B <= A?CJMPloop# 若B <= A 为真,则跳到loop处loop2: DIVFCE# F = C / EADDIF48# 将数字转化为数字字符OUTF15# 输出FSUBIF48# 将数字字符转化为数字MULGFE# G = F * ESUBCCG# C = C - GDIVEED# E = E / DLOADIA0# A = A - 100LTEEA# E <= 0?NOTC# 取反,即E > 0CJMPloop2# 若E > 0 为真,则跳到loop2处HLT# 结束拷贝字符串:#拷贝字符串BYTEstr24 = "Simulator and Assembler"BYTEs24LOADIA19LOADIB0LOADIC0LOADID0LOADIE0LOADIG0# 将数组下限设为0SUBIG4loop: LOADBBstrSTOREBBsLOADBCsADDDGEADDID48OUTC15ADDIG1LTGACJMPloopHLT编译程序源码:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#define MAX_LEN 150#define INSTRS_COUNT (sizeof(g_instrs_name)/sizeof(g_instrs_name0)#define INSTR_SYM "HLT","JMP","CJMP","OJMP","CALL","RET","PUSH","POP","LOADB", "LOADW","STOREB","STOREW","LOADI","NOP","IN","OUT","ADD", "ADDI","SUB","SUBI","MUL","DIV","AND","OR","NOR","NOTB", "SAL","SAR","EQU","LT","LTE","NOTC","BYTE","WORD" const char *g_instrs_name = INSTR_SYM; /*定义存放指令记号的数组*/const char instr_format33 = "12222133444451667575777778778881"int GetInstrCode(const char *op_sym); /*由指令助记符得到指令代码*/unsigned long TransToCode(char *instr_line, int instr_num); /*指令的译码*/int GetRegNum(char *instr_line, char *reg_name); /*由寄存器名对应到代码*/typedef struct tab int addr; /*标号偏移量*/ char str20; /*标号名称*/ struct tab *next;TAB;typedef struct byte_word int type; /*类型*/ char name8; /*变量名*/ int num; /*数组长度*/ long dat65; /*数据*/ struct byte_word *next;BYTE_WORD;TAB *head1 = NULL;BYTE_WORD *head2 = NULL;int main(int argc, char *argv) char a_lineMAX_LEN; char op_sym8; int op_num; int s = 0, k = 0, m = 0, j = 0, p = 0, q = 0; char num5; char dat5050; unsigned long str4; char *pcPos; FILE *pfIn, *pfOut; head1 = (struct tab *)malloc(sizeof(struct tab); TAB *p1 = head1; head2 = (struct byte_word *)malloc(sizeof(struct byte_word); BYTE_WORD *p2 = head2, *temp, *tail = head2; int n; if (argc < 3) /*检查命令行参数数目*/ printf("ERROR:no enough command line arguments!n"); return 0; if (pfIn = fopen(argv1, "r") = NULL) /*打开源代码文件*/ printf("ERROR:cannot open file %s for reading!n", argv1); return 0; if (pfOut = fopen(argv2, "w") = NULL) /*打开目标代码文件*/ printf("ERROR:cannot open file %s for writing!n", argv2); return 0; while (!feof(pfIn) /*处理标号和伪指令*/ fgets(a_line, MAX_LEN, pfIn); /*从源文件中取出一条指令*/ if (pcPos = strchr(a_line, '#') != NULL) *pcPos = '0' n = sscanf(a_line, "%s", op_sym); /*从指令中取指令助记符*/ if(n < 1) continue; if(strchr(a_line, ':') != NULL) /*处理标号*/ p1->addr = s; /*记录标号的行数*/ sscanf(a_line, "%:", p1->str); /*将冒号为止的字符串存入str中*/ p1->next = (struct tab *)malloc(sizeof(struct tab); p1 = p1->next; if (strcmp("BYTE", op_sym) = 0) | (strcmp("WORD", op_sym) = 0) /*处理变量*/ if(strcmp("BYTE", op_sym) = 0) p2->type = 1; else p2->type = 2; sscanf(a_line, "%*s%s", p2->name); /*存变量名*/ while(p2->namek != '0') /*去掉字符串中方括号的部分*/ if(p2->namek = '') p2->namek = '0' k+; k = 0; if(strchr(a_line, '') != NULL) sscanf(a_line, "%*%0-9", num); p2->num = atoi(num); /*将num转化为整数*/ for(m = 0; m < p2->num; m+) p2->datm = 0; m = 0; if(strchr(a_line, '=') != NULL) while (a_linej != '') && (a_linej != '"') j+; if(a_linej = '"') while(a_line+j != '"') p2->datm+ = a_linej; else while (a_line+j != '') if (isdigit(a_linej) /*如果是数字*/ datpm+ = a_linej; else if (a_linej = ',') p+; m = 0; for (j = 0; j <= p; j+) p2->datj = atoi(datj); else for(m = 0; m < p2->num; m+) p2->datm = 0; else if(strchr(a_line, '=') != NULL) sscanf(a_line, "%*=%s", dat0); p2->dat0 = atoi(dat0); p2->num = 1; else p2->num = 1; k = 0; m = 0; p = 0; q = 0; p2->next = (struct byte_word *)malloc(sizeof(struct byte_word); p2 = p2->next; continue; s+; /*行数加1*/ free(p1); free(p2); p1 = NULL; p2 = NULL; s = 0; fclose(pfIn); fclose(pfOut); pfIn = fopen(argv1, "r"); pfOut = fopen(argv2, "w"); while (!feof(pfIn) /*第二次扫描*/ fgets(a_line, MAX_LEN, pfIn); if (pcPos = strchr(a_line, '#') != NULL) *pcPos = '0' n = sscanf(a_line, "%s", op_sym); if (n < 1) | (strcmp("BYTE", op_sym) = 0) | (strcmp("WORD", op_sym) = 0) continue; if (strchr(a_line, ':') sscanf(a_line, "%*s%s", op_sym); strcpy(a_line, strchr(a_line, ':') + 1); op_num = GetInstrCode(op_sym); if(op_num > 33) printf("ERROR: %s is a invalid instruction! n", a_line); exit(-1); fprintf(pfOut,"0x%08lxn",TransToCode(a_line, op_num); s+; for (p2 = head2, k = 0, m = 0; (p2 != NULL) && (p2->num > 0) && (p2->num < 66); p2 = p2->next) if(p2->type = 1) for(s = 0, j = 0; s < p2->num; s+) strj = p2->dats; /*目的将数据倒序输出*/ j+; if(j = 4) fprintf(pfOut, "0x%02lx%02lx%02lx%02lxn", str3, str2, str1, str0); j = 0; k+; switch(j) case 1: fprintf(pfOut, "0x%08lxn", str0); break; case 2: fprintf(pfOut, "0x%04lx%04lxn", str1, str0); break; case 3: fprintf(pfOut, "0x00%02lx%02lx%02lxn", str2, str1, str0); break; case 4: fprintf(pfOut, "0x%02lx%02lx%02lx%02lxn", str3, str2, str1, str0); break; if(p2->type = 2) for(s = 0, j = 0; s < p2->num; s+) strj = p2->dats; j+; if(j = 2) fprintf(pfOut, "0x%04lx%04lx4n", str1, str0); k += 2; switch(j) case 1: fprintf(pfOut, "0x%08lxn", str0); break; case 2: fprintf(pfOut, "0x%04lx%04lxn", str1, str0); break; fprintf(pfOut, "0x%08lxn", k); fclose(pfIn); fclose(pfOut); return 1;int GetInstrCode(const char *op_sym) int i; for (i = 0; i < INSTRS_COUNT; i+) if(strcmp(g_instrs_namei, op_sym) = 0) break; return i;unsigned long TransToCode(char *instr_line, int instr_num) unsigned long op_code; unsigned long arg1, arg2, arg3; unsigned long instr_code = 0ul; char op_sym8, reg08, reg18, reg28; unsigned long addr; int immed, port; int n; char a50; switch (instr_formatinstr_num) case '1': /*第一种指令格式(HLT、RET、NOP、NOTC)的译码*/ op_code = instr_num; instr_code = op_code << 27; break; case '2': /*第二种指令格式(JMP、CJMP、OJMP、CALL)的译码*/ n = sscanf(instr_line, "%s%s", op_sym, a); if (n < 2) printf("ERROR:bad instruction format!n"); exit(-1); addr = SearchTab(a) * 4; op_code = GetInstrCode(op_sym); instr_code = (op_code << 27) | (addr & 0x00ffffff); break; case '3': /*第三种格式指令(PUSH、POP)的译码*/ n = sscanf(instr_line, "%s %s", op_sym, reg0); if (n < 2) printf("ERROR:bad instruction format!n"); exit(-1); op_code = GetInstrCode(op_sym); arg1 = GetRegNum(instr_line, reg0); instr_code = (op_code << 27) | (arg1 << 24); break; case '4': /*第四种格式指令(LOARB、LOADW、STOREB、STOREW)的译码*/ n = sscanf(instr_line, "%s %s %s", op_sym, reg0, &a); if (n < 3) printf("ERROR:bad instruction format!n"); exit(-1); addr = Search_BYTE_WORD(a); op_code = GetInstrCode(op_sym); arg1 = GetRegNum(instr_line, reg0); instr_code = (op_code << 27) | (arg1 << 24) | (addr & 0x00ffffff); break; case '5': /*第五种格式指令(LOADI、ADDI、SUBI)的译码*/ n = sscanf(instr_line, "%s %s %i", op_sym, reg0, &immed); if (n < 3) printf("ERROR:bad instruction format!n"); exit(-1); op_code = GetInstrCode(op_sym); arg1 = GetRegNum(instr_line, reg0); instr_code = (op_code << 27) | (arg1 << 24) | (immed & 0x0000ffff); break; case '6': /*第六种格式指令(IN、OUT)的译码*/ n = sscanf(instr_line, "%s %s %i", op_sym, reg0, &port); if (n < 3) printf("ERROR:bad instruction format!n"); exit(-1); op_code = GetInstrCode(op_sym); arg1 = GetRegNum(instr_line, reg0); instr_code = (op_code << 27) | (arg1 << 24) | (port & 0x0000ffff); break; case '7': /*第七种格式指令(ADD、SUB、MUL、DIV、AND、OR、NOR、SAL、SAR)的译码*/ n = sscanf(instr_line, "%s%s%s%s", op_sym, reg0, reg1, reg2);

注意事项

本文(C语言课程设计模拟器和汇编程序的设计)为本站会员(痛***)主动上传,装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知装配图网(点击联系客服),我们立即给予删除!

温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!