C语言课程设计提高部分报告.doc_第1页
C语言课程设计提高部分报告.doc_第2页
C语言课程设计提高部分报告.doc_第3页
C语言课程设计提高部分报告.doc_第4页
C语言课程设计提高部分报告.doc_第5页
已阅读5页,还剩59页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

华中科技大学计算机科学与技术学院C语言课程设计报告 题目:C语言课程设计提高部分专 业:计算机科学与技术班 级:卓越工程师班学 号:U201314810姓 名:乔一凡成 绩:指导教师:李开完成日期: 2014年 9 月 8 日第I页 共1页华中科技大学计算机科学与技术学院 C语言课程设计报告目 录一、系统需求分析1二、总体设计6三、数据结构设计8四、详细设计10五、系统实现18六、运行测试与结果分析55七、总结59八、参考文献60九、指导教师评语61I华中科技大学计算机科学与技术学院 C语言课程设计报告一、系统需求分析1、C输入输出库函数的程序设计要求(1) 给定getchar和putchar函数,实现其它C输入输出库函数。如:gets,puts,printf,scanf等。并且在原函数名前加my构成新函数名。如:mygets,myputs,myprintf,myscanf等。对myprintf函数,其功能与printf函数相同。但只要求支持简单的%c,%d,%s,%f,%lf格式说明。不要求域宽控制。对myscanf函数,其功能与scanf函数相同。但只要求支持简单的%c,%d,%s,%f,%lf格式说明。(2) 鼓励实现参考书1p241 APPENDIX B:Standard Library中B1 Input and Output: 中的其它库函数。(3) 创建mylibrary.lib库,将自己实现的库函数加入到该库中。(4) 对自行设计的每个库函数,编写实验程序,调用mylibrary.lib库自行设计的库函数,要求得到正确结果。(5) 在设计报告中提交测试结果报告以说明调用结果。(6) 提交详细注释的各个库函数清单,并且简短说明设计思路。2、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 27) & 0x0F;通用寄存器用unsigned short数组来模拟;每条指令的功能用一个无参整型函数来实现,再定义一个函数指针数组ops,将32个函数的入口地址保存到数组ops中,数组下标与函数所对应指令操作码一致,这样,从指令中解码得到指令操作码后,就可以用如下表达式调用指令功能的实现函数,模拟指令的执行。(*opsOPCODE)();接下来进行下一轮循环,直到执行函数HLT退出循环。下面是模拟器程序的流程图:开始打开文件处理代码段,数据段,堆栈段和附加段寄存器Y文件到结尾?N关闭文件取出代码PC指向第一条指令加载到内存PC+;CS = PC;N函数返回值为1?Y取指:将PC指示的指令加载到指令寄存器IRPC指向下一条执行指令解码并执行指令令结束五、系统实现字符串复制代码:BYTEstr24 = Simulator and Assembler # 要复制的字符串BYTEcopy24 #存入字符串LOADIA19#上限为19LOADIB0LOADIC0LOADIG-4#下限为-4loop: LOADBBstr#读取一个字符STOREBBcopy#存入copy中LOADBCcopyOUTC15#输出ADDIG1#下标加一LTGA#判断是否结束CJMPloop#循环HLT1加到100代码:LOADIA100# 循环的上界设为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 0CJMPloop2# 若E 0 为真,则跳到loop2处HLT# 结束编译器代码:#include #include #include #include #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 biaohao int addr; char str20; struct biaohao *next;BH;BH *head1 = NULL;typedef struct byte int type; char name8; int num; long dat65; struct byte *next;BYTE;BYTE *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 biaohao *)malloc(sizeof(struct biaohao); BH *p1 = head1; head2 = (struct byte *)malloc(sizeof(struct byte); BYTE *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 addr = s; /*记录biaohao的行数*/ sscanf(a_line, %:, p1-str); /*将冒号为止的字符串存入str中*/ p1-next = (struct biaohao *)malloc(sizeof(struct biaohao); p1 = p1-next; if (strcmp(BYTE, op_sym) = 0) | (strcmp(WORD, op_sym) = 0) /*处理byte*/ if(strcmp(BYTE, op_sym) = 0) p2-type = 1; else p2-type = 2; sscanf(a_line, %*s%s, p2-name); /*存byte名*/ 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 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 datj = atoi(datj); else for(m = 0; m 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 *)malloc(sizeof(struct byte); 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 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 next) if(p2-type = 1) for(s = 0, j = 0; s 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 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) in

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论