您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 经营企划 > 8086汇编和c语言混合实现操作系统
实验三一、实验目的1.掌握TASM汇编语言与TURBOC语言汇合编程的方法。2.实现内核与引导程序分离,掌握软盘上引导操作系统方法。3.设计并实现一种简单的作业控制语言,建立具有较友好的控制命令的批处理原型操作系统,掌握操作系统提供用户界面和内部功能的实现方法。二、实验内容在实验二的基础上,进化你的原型操作系统,增加下列操作系统功能:(1)将原型操作系统分离为引导程序和MYOS内核,由引导程序加载内核;(2)内核由汇编语言kernal.asm和c语言kernal.c二个模块生成;(3)利用C语言实现作业控制语言mJCB,原型操作系统在当前行显示一个指示符(可以是简单的一个字符或你的学号之类),允许用户输入一行命令(回车结束,语法由你设计),操作系统解释命令并完成相应的功能(3个以上的内置功能,如time、date、asc等,而且能执行软盘上的某个用户程序),并在你的实验报告中详细介绍你的mJCB语言的语法格式和功能。三、实验报告1、涉及的基础知识和实验环境工具综述、你的解决方案包括程序算法原理或流程图、程序模块说明、变量定义与作用说明、数据结构组织等A.实验环境工具综述:本次试验环境为VMware9平台上搭建的8086虚拟机,编译器为tasm,tcc,链接器为tlink,通过Winhex剪辑2进制文件,并用DiskWriter工具将主程序写入虚拟软盘,通过虚拟机加载软盘实现裸机运行。B.算法原理:a)计算机启动后,通过引导扇区加载软盘上余下的有效扇区。b)引导扇区安装必要的中断,如8号中断用以动态显示时间,21号中断用以用户程序的返回,设置栈指针,数据段指针,建立c语言运行环境,设置计数器,用以动态显示时间。配置完成后,转入基于c语言的控制程序的运行。c)基于c语言的控制程序无限重复向输入端请求命令,解析命令,跳转调用对应程序,但接收到重启命令时重启,接到关机命令时进行关机。d)系统总的实现为引导程序(osa.asm),汇编实现的c语言函数库(clib.asm),汇编实现的中断程序库(oslib.asm),c语言实现的控制台程序(osc.c)。e)由于系统已搭建c语言运行环境,并提供了相应的库,再提供一个供用户用于链接c语言程序的启动程序,用户程序即可完全由c语言实现。启动程序指定用户程序的偏移(如c9000.asm指定了用户的c程序偏移为9000h,可更改启动程序中的org来更改目标程序的偏移),并能够返回控制台(通过调用自己安装的int21H返回)。C.程序模块说明:a)clib.asm中汇编实现的c函数库externcharcls();功能:清屏,清空第0页的显存输入:无返回:无externintputs(constchar*str);功能:向当前光标位置输出字符串输入:字符串首地址返回:输出字符个数externchar*gets(char*str);功能:读取字符串输入:字符串首地址返回:字符串首地址externintstrlen(constchar*str);功能:求以0结束的字符串的长度输入:字符串首地址返回:字符从长度externintgetchar(void);功能:读取字符输入:无返回:字符的ascii码externintputchar(intc);功能:输出字符输入:字符c返回:字符cexternunsignedintport_in8(unsignedintport);功能:从port端口读入8位数据输入:端口号返回:读取的数据externunsignedintport_in16(unsignedintport);功能:从port端口读入16位数据输入:端口号返回:读取的数据externvoidport_out8(unsignedintport,unsignedintvalue);功能:向port端口输出8位数据value输入:端口号和数据返回:无externvoidport_out16(unsignedintport,unsignedintvalue);功能:从port端口输出16位数据value输入:端口号和数据返回:无externvoidsetp_cursor(unsignedintbh,unsignedintdh,unsignedintdl);功能:将第bh页的指针置于dh行dl列输入:页号bh,行号dh,列号dl返回:无externvoidrun_pro(intord);功能:运行程序地址表中第ord号程序输入:程序序号返回:无b)主控制程序:osc.cexterncharcls();externintputs(constchar*str);externchar*gets(char*str);externintstrlen(constchar*str);externintgetchar(void);externintputchar(intc);externunsignedintport_in8(unsignedintport);externunsignedintport_in16(unsignedintport);externvoidport_out8(unsignedintport,unsignedintvalue);externvoidport_out16(unsignedintport,unsignedintvalue);externvoidsetp_cursor(unsignedintbh,unsignedintdh,unsignedintdl);externvoidrun_pro(intord);voidinttostr(intx,char*str);intstrtoint(char*str);unsignedintbcdtodex(unsignedintx);voidget_date(char*buf);/*yy-mm-dd*/voidset_date(char*buf);voidget_time(char*buf);/*hh:mm:ss*/voidset_time(char*buf);voidpre_time();voidinterface();intstrcmp(charstr1[],charstr2[]);voidatoA(char*buf);intdeal(char*buf);intinside(intmin,intmax,intx);intchange_time(intparas);intislegal(inty,intm,intd);intchange_date(intparas);intshutdown(intparas);intreboot(intparas);intjc(intparas,char*buf);charbuffer[80];intcontrol=1;charExit_Message[30]=\nPressanykeytoexit...;unsignedintadd_Table[30]={0x9000,0,0xa000,0,0xb000,0};cmain(){intparas;control=0;while(1){cls();interface();gets(buffer);setp_cursor(0,6,0);paras=deal(buffer);if(paras!=0){jc(paras,buffer);puts(Exit_Message);getchar();}}}c)用户程序:cx0.ccx1.c2、实验步骤、操作的主要过程、运行结果、屏幕画面截图等A.实验步骤a)编写代码b)在dosbox上执行批处理文件0.bat,得到os.com,执行9000.bat得到用户程序1,执行a000.bat得到用户程序2c)使用WinHex将os.com中7e00h到结束的所有数据写到虚拟软盘文件Tinix.img偏移为0的位置处,将用户程序1和用户程序2对应的代码写到1400h和2400h处。d)从软盘启动虚拟机B.屏幕截图a)开机界面b)时间设置c)日期设置d)运行程序地址表中的用户程序e)指令参数错误检查f)执行重启命令,由于重启时无法截图,只提供命令输入界面g)关机指令C.指令总结a)Time修改cmos时间,不需要参数b)Date修改cmos日期,不需要参数c)Runx执行第x号用户程序,1=x=2,安装新程序x需扩展。d)Reboot重启,不需要参数e)Shutdown关机,不需要参数四、实验心得体会A.程序c语言环境的配置和实现,应基于编译器tcc默认的调用规范cdecl。a)cdecl在8086上对c语言参数的入栈顺序为从右向左入栈,对栈的恢复由程序调用者caller实现,汇编实现c语言函数库时,不需要在函数中对栈进行恢复。在汇编程序中调用c实现的函数,对参数压栈和对函数返回后要注意恢复。b)cdecl对函数的返回值,8位,16位和32位分别存放于al、ax、dx和ax中,汇编中调用c实现的函数时返回值的获取为以上寄存器。c)cdecl只对ds,ss,bp,si,di等寄存器进行保护。当在汇编中调用c实现的函数时,若通用寄存器ax,bx,cx,dx中存在有意义的值,要自行进行压栈保护。B.实现tcc的过程中,发现tcc在栈的处理上存在bug。tcc编译tcc_bug文件得到的二进制文件,通过debug反汇编解析,发现,tcc对函数中的临时字符串buf的取值从[bx+offset]中取(产生错误的位置在tcc_bug.c文件中有标注),而bx默认的段地址为ds而不是ss。当ds不等于ss时,会取出错误的值,产生乱码。解决方法:通过在引导程序中配置c语言环境时ds和ss设置相同的值,成功解决产生乱码的问题。C.由于8086程序在dos上运行是使用int21h的4ch号功能返回控制台,本次实验对安装了仅有单个iret指令的21h中断,来实现初步对dos程序的小的兼容,用于与用户的c语言链接的启动程序使用int21h调用安装的iret进行返回控制台。Osc.cexterncharcls();externintputs(constchar*str);externchar*gets(char*str);externintstrlen(constchar*str);externintgetchar(void);externintputchar(intc);externunsignedintport_in8(unsignedintport);externunsignedintport_in16(unsignedintport);externvoidport_out8(unsignedintport,unsignedintvalue);externvoidport_out16(unsignedintport,unsignedintvalue);externvoidsetp_cursor(unsignedintbh,unsignedintdh,unsignedintdl);externvoidrun_pro(intord);voidinttostr(intx,char*str);intstrtoint(char*str);unsignedintbcdtodex(unsignedintx);voidget_date(char*buf);/*yy-mm-dd*/voidset_date(char*buf);voidget_time(char*buf);/*hh:mm:ss*/voidset_time(char*buf);voidpre_time();voidinterface();intstrcmp(charstr1[],charstr2[]);voidatoA(char*buf);intdeal(char*buf);intinside(intmin,intmax,intx);intchange_time(intparas);intislegal(inty,intm,intd);intchange_date(intparas);intshutdown
本文标题:8086汇编和c语言混合实现操作系统
链接地址:https://www.777doc.com/doc-5261778 .html