ImageVerifierCode 换一换
格式:DOCX , 页数:17 ,大小:59.50KB ,
资源ID:2266847      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/2266847.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(编写实模式多任务操作系统模型之二.docx)为本站会员(b****2)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

编写实模式多任务操作系统模型之二.docx

1、编写实模式多任务操作系统模型之二在前面,我们了解了X86模式的功能特点,运行机制并对程序模块进行了分析。下面将继续分析程序模块的进程调度子程序和其他辅助程序,并完成这个程序的编译及安装运行。 进程调度子程序scheduler scheduler是系统的进程调度程序,是实现多任务关键的部分。它实质上是嵌入到系统时钟中断内来完成进程调度功能的。由于系统时钟以18.2次/秒的频率发生中断,这样每当时钟中断一发生,便可带动进程调度程序执行,所以这个OS模型是以时钟中断来驱动的。为了不影响原来时钟中断程序的例行工作,它开始运行时首先要调用位于ROMBIOS中的 0xF000:0xFEA5 处的时钟中断服

2、务程序。返回后,它从current_task单元中找到当前被中断进程的进程号,根据该进程号在SPtable中找到其进程栈指针的存放地址,将其栈指针存入到该地址中,为下一次运行做好准备。而后将 current_task 加1,得到下一个将被调度运行的进程号。由该进程号在 SPtable 中找到上一次该进程被中断时的进程栈指针,将CPU的SP寄存器设为该值,这样堆栈指针便指向进程栈的栈顶。由于每次进程被中断运行时在进程栈顶都保存有断点处的CPU内部通用寄存器及ES和DS的值,此时将这些值恢复到相应的寄存器中,最后通过一条IRET指令便可将CPU的控制权转移到这一进程上,这个进程便重新从断点处重新运

3、行。整个系统便在调度程序的控制下循环往复地运行,依次将CPU分时地切换到各个进程上。由于切换的速度较快,所以宏观上我们便看到几个进程在同时向前并行推进,互不影响。在微观上,几个进程轮流占用CPU,分时运行。 Scheduler初次被激活是Kernel全部初始化工作完成后。Kernel初始化工作完成后,各个进程堆栈空间布局均如图7所示的形式,其中“Task1偏移地址”单元中为相应进程入口地址的偏移地址。在Kernel程序中: jmp $ ; kernel在此等待时钟中断的到来该指令相当一条无穷循环指令 while(1);,当时钟中断到来时,它将从无穷循环中转到scheduler去执行,而后每一次

4、时钟中断都引起scheduler的运行,这时的各个进程堆栈空间布局仍有如图7所示的形式,只不过此时堆栈的底端由于进程的运行已经有进程所压入的数据,留下了进程运行过的痕迹,如图8所示。调度程序运行流程如图9所示。 具体工作步骤如下(假设调度程序运行前,CPU正处于task1的进程空间,SP指向task1的进程堆栈的栈顶,此时发生时钟中断,scheduler投入运行): 1.调度程序将task1进程断点处的CPU内部通用寄存器及ES和DS的值压入到task1进程堆栈中,代码如下: pusha push es push ds2.向中断控制器8259发送EOI中断结束指令: mov al, 0x20o

5、ut 0x20, al3.将标志寄存器Flag压入堆栈,调用位于ROMBIOS中的 0xF000:0xFEA5 处的原时钟中断服务程序,使原时钟中断服务程序完成其原有的工作,代码如下: pushfcall 0xF000:0xFEA5由于原时钟中断为硬件中断,所以中断服务程序返回指令为iret。iret指令依次将栈顶字单元的内容弹出到IP、CS及Flag中,这样为了保证上述call指令的正确返回及堆栈不被破坏,所以要在call指令的前面加入pushf指令,以和iret的动作相配合。 4.保存将被剥夺执行权的task1进程堆栈指针。由于进程堆栈中保存有进程被中断时的断点信息,而其它进程运行时也要使

6、用CPU内部的SP寄存器,所以在进行任务切换前要做进程的堆栈指针的保存工作。如下指令所示: mov ax, current_taskmov bx, axshl bx, 1 lea si, SPtablemov ds:si + bx, SP在current_task内存中存放当前运行进程的进程号,以为索引可以在 SPTABLE 数组中找到该进程堆栈指针的存放地址,即进程堆栈指针的存放地址=SPtable+2*进程号,找到该地址将进程断点处的SP存入其中。5切换到下一将被调度运行task2的进程堆栈空间。由于在进程堆栈保存有进程的断点信息,所以找到进程堆栈的顶位置便可转入到该进程运行。schedu

7、ler对于各进程的调度采用轮转式的方式,即按照task1 - task2 - task3的顺序,而后再从task1 开始依次循环,使各个进程得以运行。所以将current_task的值增1,再判断current_task是否超过最大进程数MAXTASKS,若超过,则使其复位,从0开始重新计数即可。取得合适的current_task值后,按上面步骤的公式便可找到将被调度进程的堆栈指针的存放地址,从中取出值送到SP寄存器即可。如下段程序代码所示: inc ax ; 取得下一将被调度进行的进程号 cmp ax, MAXTASKS ; 该进程号是否超过最大进程数 jb move_on ; 若没超过,跳

8、到 move_on 继续 xor ax, ax ; 超过最大进程数,清0,从第一个进程开始调度move_on:mov current_task, ax ;将更改后进程号送入current_task单元保存,按公式进程堆栈指针的存放地址=SPtable+2*进程号 取得进程堆栈指针 mov bx, ax shl bx, 1 lea si, SPtable mov SP, ds:si + bx ; 将进程堆栈指针送到SP,切换到进程堆栈空间6 恢复断点信息,使下一被调度进程从断点处运行。 pop ds pop es popa ;恢复所有被保存的CPU内寄存器值iret ;激活被调度进程其它辅助程序

9、 系统中存在3个被调度的程序,分别为task1、task2、task3。由于这是一个实验程序,所以它们的功能较为单一,主要是将自身的一个16位计数器进行循环计数,而后通过直接写屏方式在显示器上显示出来。由于现行机器的运行速度较快,为使用户能看清计数器的变化过程,在各个进程的执行过程中加入了人为的延时控制。每一个进程都是一个无限的循环过程,只要调度程序在运行,各个进程就会无限运行。 此外系统中还有几个辅助程序: 16进制数显示子程序printhex 这个子程序主要是为系统内的3个演示进程服务,它可以将从堆栈传递过来的一个16位的数以16进制形式显示到屏幕的指定位置,通过直接写屏方式在显示器上显示

10、出来。在VGA的 80X25 彩色文本显示模式下,一个字符在显示缓冲区上占2个字节的空间,其中所显示字符的ASC码存于低地址单元中,字符的显示属性(前景、背景、高亮和闪烁等)存于高地址单元中,如果将字符及其显示属性存储位置弄错,将会产生花屏的现象。Printhex根据显示位置参数计算出所需显示的准确位置,避免产生花屏的现象。调用者只需提供合法的显示位置即可,行号应在125之间,列号在180之间。 键盘中断子程序keybd 它是一个基本的内核级键盘中断处理程序,显示键盘的ASC码到屏幕上。它不受调度进程的控制,只要有键盘中断发生,该中断服务程序就会运行。在该程序被触发运行时,从60H端口读入键盘

11、的扫描码。扫描码最高位的状态标志着其是键入码还是释放码,如为释放码则不进行处理,直接返回;若为按键的压入码,则以键入码作为索引在键盘扫描码/ASC码对照表查得对应的ASC码,通过int 10h功能调用将其输出到显示器上。在键盘中断返回前,要向键盘内的单片机发复位信号, 先将61h端口的最高位置1,而后再置0,这样键盘才不会死锁。 kernel.asm完整代码及注释如下: ; 内核程序kernel.asm; 在系统时钟中断的驱动下,依次使系统内的3个进程轮流占用CPU完成各; 自的工作:在屏幕上指定位置循环显示自己的计数器。具有内核级键盘中; 断,显示出键盘ASCII码;BITS 16ORG 0

12、x00 STACKSIZE equ 0x400 ; 各进程的堆栈空间大小为1k个字节MAXTASKS equ 3 ; 最大进程数 VIDEORAM equ 0xb800 ; 显示缓存段地址 KERNELSEG equ 0x8000 ; kernel 程序段地址 ;-start: mov ax,KERNELSEG mov ds, ax ; 数据段,堆栈段寄存器的 mov ss, ax ; 值均设为 KERNELSEG mov sp, 0xFFFF ; kernel 堆栈指针=0xFFFF mov dx,0x3f2 mov al,0x0c out dx,al ;关闭软驱马达 mov ax, 0x0

13、003 int 0x10 ; 清屏 mov dx, 0x0600 ; 进程的堆栈基地址 add dx, STACKSIZE ; 进程1的堆栈指针= 0xA00 mov ax, task1 ; 进程1入口地址 call taskinit ; 初始化进程1 add dx, STACKSIZE ; 进程2的堆栈指针= 0xD00 mov ax, task2 ; 进程2入口地址 call taskinit ; 初始化进程2 add dx, STACKSIZE ; 进程3的堆栈指针= 0x1000 mov ax, task3 ; 进程3入口地址 call taskinit ; 初始化进程3 ; 重新设置

14、系统定时器的中断向量 cli ;关中断,以免在设置中断向量发生意外 mov ax, KERNELSEG push ds ;保存ds值 mov bx,0 mov ds,bx ;ds=0 mov word ds:0x08*4, scheduler ; 定时器中断向量偏移送到0:200:21 mov word ds:0x08*4+2, ax ; 定时器中断向量段地址送到0:220:23 ; 重新设置键盘的中断向量 mov word ds:0x09*4, keybd ; 键盘的中断向量偏移送到0:240:25 mov word ds:0x09*4+2, ax ; 键盘的中断向量段地址 0:260:27 pop ds ; 恢复ds值 sti ; 开中断,允许中断进入 jmp $ ; kernel在此等待时钟中断的到来 ; 被调度进程task1 ; 功能:对于自身的计数器进行计数,而后在屏幕的3行1显示输出;task1:.l1 dec word task1ctra ; 产生短时间延迟,以免计数显示过快

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1