系统软件开发实践报告_第1页
系统软件开发实践报告_第2页
系统软件开发实践报告_第3页
系统软件开发实践报告_第4页
系统软件开发实践报告_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

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

文档简介

1、计算机科学与技术学院系统软件开发实践报告姓 名: 王冬升 学 号: 08123228 专 业: 计算机科学与技术 班 级: 计科12-1班 指导教师: 张 博 2015年 4月 摘 要操作系统和编译原理是大学计算机专业的必修课程。在这些课程的教学教程中,容易偏重于理论的介绍,而忽视了实践环节。本课程设计是在完成C+程序设计、数据结构、操作系统、编译技术教学后所进行的,全面综合训练学生的系统软件开发能力关键字:编译系统、Flex、Bison、操作系统、启动、内存管理目 录1 借助Flex进行词法分析 2 1.1实验内容 2 1.2 实验要求 2 1.3 程序代码 2 1.4 实验结果 42 借助

2、Flex/Bison进行语法分析 5 2.1 实验内容 5 2.2 实验要求 52.3 程序代码 52.4 实验步骤 52.5 实验结果 73 Flex/Bison综合实验 7 3.1 实验内容 7 3.2 计算器具体需要实现的功能 7 3.3 实验要求 7 3,4 程序代码 8 3.5 实验结果 114(操作系统实验)lib0:熟悉实验环境 114.1 实验目的 114.2 实验环境搭建 114.3 GCC编译练习 124.4 GDB调试练习 125(操作系统实验)lib1:启动操作系统 135.1 实验目的 135.2 实验内容 145.3 实验步骤 145.4 操作系统启动过程 155.

3、5 实模式与保护模式 166(操作系统实验)lib2:物理内存管理 166.1 实验目的 166.2 实验内容 166.3 7实验体会 8参考文献 1借助Flex进行词法分析1.1实验内容给定C语言的一个子集,具体内容如下:1. 下面是语言的关键字: else if switch for int float return void while 所有的关键字都是保留字,并且必须是小写。2. 下面是专用符号: + - * / = = != = ; , ( ) /* */3. 其他标记是标识符(ID) 和数字(NU ),通过下列正则表达式定义:ID = letter letter*NUM = dig

4、it digit*letter = a|.|z|A|.|Zdigit = 0|.|9 注:小写和大写字母是有区别的。4. 空格由空白、换行符和制表符组成。空格通常被忽略,除了它必须分开ID、NUM 关键字。5. 注释用通常的C语言符号/* . . . */围起来。注释可以放在任何空白出现的位置(即注释不能放在标记内)上,且可以超过一行。注释不能嵌套1.2实验要求编写 LEX 源文件,实现C 语言子集的词法分析功能,最后上机调试。要求编写一个测试程序,以给定的测试文件作为输入,输出运行结果到输出文件中1.3程序代码Lex.l源码:%#include #include #include int y

5、ywrap();int lineno=1;%delim t ws delim+ letter A-Za-zdigit 0-9id letter+number digit+enter nspchar (|(|)|;|=|,|+|-|*|/|=|=|!=)comment /*(*/|*)*/kwd (else|if|switch|for|int|float|return|void|while)%ws comment enter lineno+;kwd fprintf(yyout,%d行tkeywodt%sn,lineno,yytext);spchar fprintf(yyout,%d行tspcha

6、rt%sn,lineno,yytext);id fprintf(yyout,%d行tidentit%sn,lineno,yytext);number fprintf(yyout,%d行tnumbert%sn,lineno,yytext);.%int yywrap() return 1;int main(void)char infilename100;printf(输入文件名:);scanf(%s,infilename);yyin = fopen(infilename,r);yyout = fopen(out,w);yylex();return 0;测试程序:1-1.cpp#includeusi

7、ng namespace std;int main() int a;int d=123456;float b=123.45;int e=9;a=(1+2-1)*4/2;if(ab)coutbendl;else couta=bendl;coutaendl;coutbendl;coutWelcome to c+ endl;return 0;1.4实验结果实验结果输出到.out文件中,截图示例:2借助Flex/Bison进行语法分析2.1实验内容利用附录提供的C语言文法的相关参考资料,利用Yacc/Bison编写一个C语言分析器。具体内容:1) 利用语法分析器生成工具Bison编写一个语法分析程序,

8、与词法分析器结合能够根据语言的上下文无关文法,识别输入的单词序列是否文法的句子2) 利用附录提供的C语言文法的相关参考资料,利用Yacc/Bison编写一个C语言分析器。 2.2 实验要求1) 编写 Bison源文件,实现C 语言的语法分析功能,最后上机调试。2) 要求编写一个测试程序,以给定的测试文件作为输入,输出运行结果到输出文件中。2.3程序代码由于本实验的lex源文件和yacc源文件代码较长而且在“实验附录:C语言相关文法”文件夹中已经给出相关源码的链接,由于报告篇幅限制不再贴出源码Test.测试文件源码:void main() int i = 0;int j = 0;void t1(

9、) int i = 0;typedef unsigned int uint;uint xx;uint yy;2.4实验步骤 1、flex -l input.lexbison -d cgrammar-new.y (产生头文件和.c文件)2、comment函数调用yyinput,编译会有链接错误,解决方法一,将lex.yy.c中的yyinput函数定义拷贝一份到input.lex, 重命名为my_yyinput, 或者将lex.yy.c中的#ifdef _cplusplusstatic int yyinput()#elsestatic int input()#endif改为static int y

10、yinput()上述问题出现的情形:词法分析器的后缀名为.c, 而不是.cpp3、cgrammar-new.tab.c中如下程序段/*-.| yyparse. |-*/#ifdef YYPARSE_PARAM# if defined (_STDC_) | defined (_cplusplus)int yyparse (void *YYPARSE_PARAM)# elseint yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM;# endif#else /* ! YYPARSE_PARAM */#if defined (_STDC_) | defined

11、(_cplusplus)intyyparse (void)#elseintyyparse () ;#endif#endif改为int yyparse () 或者 int yyparse (void)4、lex.yy.c中,将下面语句注释if ( ! yyin )yyin = stdin;5、解析之前,设置yyin为输入文件指针extern FILE *yyin;if(!(yyin = fopen(filename,r) printf(the file not existn); exit(0);2.5实验结果 实验结果输出到.out文件中,截图示例:3 Flex/Bison综合实验3.1实验内容

12、使用flex和bison开发了一个具有全部功能的桌面计算器,能够支持变量,过程,循环和条件表达式,使它成为一个虽然短小但是具有现实意义的编译器。重点学习抽象语法树的用法,它具有强大而简单的数据结构来表示分析结果3.2计算器具体需要实现的功能变量命名;实现赋值功能;实现比较表达式(大于、小于、等于等等)实现if/then/else和do/while的流程控制;用户可以自定义函数;简单的错误恢复机制3.3实验要求编写 Flex/Bison源文件,实现C 语言的语法分析功能,最后上机调试。要求编写一个测试程序:1) 首先自定义两个函数sq和avg,sq函数使用Newton方法来迭代计算平方根;avg

13、函数计算两个数值的平均值。2) 利用定义好的函数进行计算,得到计算结果并显示出来3.4程序代码Cal.l源码% #include cal.tab.h%option noyywrapinteger 0-9+dreal (0-9*.0-9+)ereal (0-9*.0-9+EedD+-?0-9+)real dreal|erealnl nplus +minus -times *divide /lp (rp )module %power % t ; /*skip any blanks */integer sscanf(yytext, %d, &eger); return INTEG

14、ER;real sscanf(yytext, %lf, &yylval.real);/*yylval = atof(yytext); it doesnt work under MSVSC*/ return REAL; plus return PLUS;minus return MINUS;times return TIMES;divide return DIVIDE;module return MODULE;power return POWER;lp return LP;rp return RP;nl return NL;. return yytext0;Cal.y源码%#include #i

15、nclude %union double real; /* real value */ int integer; /* integer value */%token REAL%token INTEGER%start lines%token NUMBER NL%token PLUS MINUS TIMES DIVIDE MODULE POWER LP RP%type rexpr%type iexpr%left PLUS MINUS /*left associative */%left TIMES DIVIDE MODULE /*left associative */%left POWER%lef

16、t UNARYMINUS%lines: /* nothing */ | lines line NL | lines error NL yyerror();yyerrok; ;line : iexpr printf(%dn,$1); | rexpr printf(%lfn,$1); ;iexpr: INTEGER $ = $1; | iexpr PLUS iexpr $ = $1 + $3; | iexpr MINUS iexpr $ = $1 - $3; | iexpr TIMES iexpr $ = $1 * $3; | iexpr DIVIDE iexpr if($3) $ = $1 /

17、$3; else $ = $1; printf (stderr, %d.%d-%d.%d: division by zero, 3.first_line, 3.first_column, 3.last_line, 3.last_column); | iexpr MODULE iexpr $ = $1 % $3; | iexpr POWER iexpr $ = pow($1, $3); | MINUS iexpr %prec UNARYMINUS $ = - $2; | LP iexpr RP $ = $2; | LP iexpr error $ = $2; yyerror(missing );

18、 yyerrok; | PLUS iexpr %prec UNARYMINUS $ = $2; rexpr :REAL $ = $1; | rexpr PLUS rexpr $ = $1 + $3; | rexpr MINUS rexpr $ = $1 - $3; | rexpr TIMES rexpr $ = $1 * $3; | rexpr DIVIDE rexpr if ($3)$ = $1 / $3; else $ = $1; printf (stderr, %d.%d-%d.%d: division by zero, 3.first_line, 3.first_column, 3.l

19、ast_line, 3.last_column); | rexpr POWER rexpr $ = pow($1,$3); | LP rexpr RP $ = $2; | LP rexpr error $ = $2; yyerror(missing ); yyerrok; | MINUS rexpr %prec UNARYMINUS $ = -$2; | PLUS rexpr %prec UNARYMINUS $ = $2; | iexpr PLUS rexpr $ = (double)$1 + $3; | iexpr MINUS rexpr $ = (double)$1 - $3; | ie

20、xpr TIMES rexpr $ = (double)$1 * $3; | iexpr DIVIDE rexpr if($3) $ = (double)$1 / $3; else $ = $1; printf (stderr, %d.%d-%d.%d: division by zero, 3.first_line, 3.first_column, 3.last_line, 3.last_column); | iexpr POWER rexpr $ = pow(double)$1,$3); | rexpr PLUS iexpr $ = $1 + (double)$3; | rexpr MINU

21、S iexpr $ = $1 - (double)$3; | rexpr TIMES iexpr $ = $1 * (double)$3; | rexpr DIVIDE iexpr if($3) $ = $1 / (double)$3; else $ = $1; printf (stderr, %d.%d-%d.%d: division by zero, 3.first_line, 3.first_column, 3.last_line, 3.last_column); | rexpr POWER iexpr $ = pow($1,(double)$3); ;%void main() yypa

22、rse();int yyerror(char* msg)printf(Error: %s encountered n, msg);3.5实验结果实验结果截图:4(操作系统实验)lib0:熟悉实验环境4.1实验目的1) 了解操作系统开发实验环境2) 熟悉命令行方式的编译、调试工程3) 掌握基于硬件模拟器的调试技术4) 熟悉C语言编程和指针的概念5) 了解X86汇编语言4.2实验环境搭建1) 在线实验-基于实验楼在线平台2) Windows下基于MingW进行实验3) Windows下基于VirtualBox or VMWare进行实验4) 在MAC OS下进行实验5) 手动在物理PC中安装环境4

23、.3 GCC编译练习采用实验环境:在线实验-基于实验楼在线平台gcc示例:#includeint main(void)printf(hello!n);return 0;在实验环境中右键-从模板创建-空文件,将上述示例代码输入1) 保存为hello.c打开命令行,输入以下命令:2) 编译:gcc -Wall hello.c -o hello3) 执行:./hello操作及结果截图:4.4 GDB调试练习 1)输入命令:gcc -o hello hello.c g进行编译 2)输入命令:gdb进入调试 3)依次输入以下命令熟悉gdb调试file hello:进入hello文件run:运行hello

24、break 1:在第一行插入断点next:单步执行下一行语句clear 1:清除第一行的断点list :显示hello文件的内容quit:退出gdb调试对应命令执行结果截图:GDB的其它调试命令补充:next :单步到程序源代码的下一行,不进入函数。nexti :单步一条机器指令,不进入函数。step :单步到下一个不同的源代码行(包括进入函数)。stepi :单步一条机器指令他们功能各不相同,区别在于单步的“跨度”上。5(操作系统实验)lib1:启动操作系统5.1实验目的操作系统是一个软件,也需要通过某种机制加载并运行它。在这里我们将通过另外一个更加简单的软件-bootloader来完成这些

25、工作。为此,我们需要完成一个能够切换到x86的保护模式并显示字符的bootloader,为启动操作系统ucore做准备。lab1提供了一个非常小的bootloader和ucore OS,整个bootloader执行代码小于512个字节,这样才能放到硬盘的主引导扇区中。通过分析和实现这个bootloader和ucore OS,读者可以了解到:1)计算机原理CPU的编址与寻址: 基于分段机制的内存管理CPU的中断机制外设:串口/并口/CGA,时钟,硬盘2)Bootloader软件编译运行bootloader的过程调试bootloader的方法PC启动bootloader的过程ELF执行文件的格式和

26、加载外设访问:读硬盘,在CGA上显示字符串3)ucore OS软件编译运行ucore OS的过程ucore OS的启动过程调试ucore OS的方法函数调用关系:在汇编级了解函数调用栈的结构和处理过程中断管理:与软件相关的中断处理外设管理:时钟5.2实验内容lab1中包含一个bootloader和一个OS。这个bootloader可以切换到X86保护模式,能够读磁盘并加载ELF执行文件格式,并显示字符。而这lab1中的OS只是一个可以处理时钟中断和显示字符的幼儿园级别OS。5.3实验步骤熟悉以下命令,掌握操作系统的启动过程:1) make(ucore.img的生成过程)2) make V=(g

27、cc把c的源代码编译成.o的目标文件 ld会把这些目标文件呢会转换成一个执行程序,这里面会转换成这个bootblock.out这个实际上是可以理解为是一个Bootloader一个执行程序,第一个是Bootloader 第二叫kernel)3)启动系统:make qemu4)启动并调试:make debug:进入debug模式n(执行下一行代码)p ph(显示当前值)continue(继续执行)ctrl+c(中断)quit(推出5.4操作系统启动过程当X86一开始加电时候,启动是实模式(实地址寻址模式)(早期的为了ss向下兼容以前的80X86一开始启动是16位的实模式)第一条地址:段地址寄存器C

28、SCS和EIP结合在一起来决定它启动的第一条地址:按实模式的寻址方式:cs(base)基址+EIP-bios(指向bios)这个bios固件会去加载磁盘或者硬盘的第一个主引导扇区(即执行0号扇区 lab1中的bootloader)它完成来对我们说的这个操作系统 uCore的进一步加载Bootloader的工作:1)要从实模式切换到保护模式,就是从实模式的16位的寻址空间切换到了32位的寻址空间寻址空间:从1M(物理地址=左移4位的段地址+偏移地址)变为4G,段机制可以正常工作了。对系统寄存器CRO(或者叫控制寄存器 )把它的第0号bit置成1那么就意味着现在的系统我们的CPU会进入到保护模式2

29、)就是读取kernel 就是uCore的代码,CS EIP的值指向我们操作系统内核所在内存中的起始点,之后就相当于是把控制权交给了uCore OS去执行5.5实模式与保护模式(1) 实模式在bootloader接手BIOS的工作后,当前的PC系统处于实模式(16位模式)运行状态,在这种状态下软件可访问的物理内存空间不能超过1MB,且无法发挥Intel 80386以上级别的32位CPU的4GB内存管理能力。实模式将整个物理内存看成分段的区域,程序代码和数据位于不同区域,操作系统和用户程序并没有区别对待,而且每一个指针都是指向实际的物理地址。这样,用户程序的一个指针如果指向了操作系统区域或其他用户程序区域,并修改了内容,那么其后果就很可能是灾难性的。通过修改A20地址线可以完成从实模式到保护模式的转换(2) 保护模式只有在保护模式下,80386的全部32根地址线有效,可寻址高达4G字节的线性地址空间和物理地址空间,可访问64TB(有214个段,每个段最大空间为232

温馨提示

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

评论

0/150

提交评论