实验11 多任务和多线程

 

实验11

保护模式支持多任务,能够快速地进行任务切换和保护任务环境。在Windows操作系统中,它能同时运行若干个应用程序(独立运行的程序又称之为进程),每一个进程作为一个任务;在一个进程中,它又可以分成若干个独立的执行流,称之为线程。

11.1 多任务及其调度

下面给出一个用于演示任务切换的实例。该程序在保护模式下建立2个任务,分别在屏幕上显示单个字符和寄存器的值。涉及的内容包括:直接通过TSS段的任务切换,通过任务门的任务切换,任务内特权级的变换及参数传递。

1. 实现步骤

第一个任务称为临时任务,另一个任务称为演示任务。临时任务的代码位于TempCodeSeg段,从标号Virtual处开始执行;演示任务的代码位于DemoCodeSeg段,从标号DemoBegin处开始执行。演示任务还调用了SubRSeg段中的SubRB子程序。

程序执行过程如下:

(1) 实模式下初始化(Start);

(2) 切换到保护模式(JUMP16  <TempCode_Sel>,<OFFSET Virtual>指令);

(3) 设置TR对应临时任务,特权级为0Virtual);

(4) 直接切换到演示任务,演示任务的特权级为2JUMP16  DemoTSS_Sel,0);

(5) 把入口参数压入堆栈,经调用门进入显示信息子程序,显示信息子程序的特权级为0DemoBegin);

(6) 从堆栈中取出入口参数并处理(SubRB);

(7) 从显示信息子程序返回特权级为2的演示代码段(ret 8);

(8) 经任务门切换到特权级为0的临时任务(JUMP32  ToTempT_Sel,0);

(9) 循环执行(4)~(8)任务切换5次(loop指令)。

(10) 切换到实模式(JUMP16  <SEG Real>,<OFFSET Real>);

(11) 实模式下的恢复工作(Real)。

程序中包括以下内容:

(1) 实模式下的数据段(RDataSeg)。其中包括全局描述符表GDT

(2) 演示任务的LDT段(DemoLDTSeg)。

(3) 演示任务的TSSDemoTSSSeg)。

(4) 演示任务的0级和2级堆栈段(DemoStack0SegDemoStack2Seg)。

(5) 演示任务数据段(DemoDataSeg)。

(6) 子程序代码段(SubRSeg)。

(7) 演示任务代码段(DemoCodeSeg)。

(8) 临时任务的TSS段(TempTSSSeg)。

(9) 临时任务的代码段(TempCodeSeg)。

(10) 实模式下的堆栈段(RStackSeg)。

(11) 实模式下的代码段(RCodeSeg)。

DemoLDT中,含有以下局部描述符,这些描述符只能被临时任务所使用:

(1) 演示任务的0级和2级堆栈段描述符(DemoStack0DemoStack2

(2) 代码段描述符(DemoCode

(3) 数据段描述符(DemoData

(4)  LDT所在数据段的描述符(ToDLDT

(5) 临时任务TSS所在数据段的描述符(ToTTSS

(6) 指向子程序的调用门(ToSubR

(7) 指向临时任务的任务门(ToTempT)。

其中,在定义前5项描述符时,其基地址为各个段的实模式段基值(16位)。因此,调用InitLDT子程序,将段基值乘以16以后,得到这些段的物理地址(20位),再存放到BaseHBaseMBaseL字段中。

GDT中的DemoLDTabDemoTSSTempTSSTempCodeSubR也由InitGDT子程序进行了同样处理。

2. 从临时任务切换到演示任务

TR未在实模式下设置,切换到保护模式后,要把指向临时任务TSS描述符的选择符(TempTSS_Sel)装入TR。之后,才能执行任务切换。利用LTR指令为TR赋值时,并不引用TSS的内容,所以临时任务的TSS不需要被初始化。

在任务切换时,把原任务的现场保存到TR所指示的TSS内,然后再把指向目标任务的TSS描述符的选择符装入TR。从临时任务切换到演示任务时,执行“JUMP16  DemoTSS_Sel, 0 指令,切换过程包括:把临时任务的执行现场保存到临时任务的TSS中;把演示任务的LDT描述符选择符(DemoLDT_Sel)装载到LDTR;从演示任务的TSS中恢复演示任务的现场等。

TempTSSSeg中,演示任务TSSCS字段存放的是DemoCode_Sel,对应的描述符是DemoLDT中的DemoCode,其DPL=2EIP字段存放的是DemoBegin,所以在切换到演示任务后从DemoBegin开始执行,并且CPL=2。由于使用JMP指令进行任务切换,所以不实施任务链接。

3. 演示任务内的特权级变换和

演示任务采用段间调用指令CALL,通过调用门ToSubR调用子程序SubRB。调用门内的它所指示的子程序代码段描述符(SubR_Sel)的DPL=0,所以在调用过程中就发生了从特权级2到特权级0的变换,同时堆栈也被切换到DemoStack0Seg

通过堆栈传递了两个参数给子程序SubRB。在把参数压入堆栈时,CPL=2,使用的也是对应特权级2 的堆栈(DemoStack2Seg)。通过调用门进入子程序后,CPL=0,使用0级堆栈。为此,把调用门ToSubR中的DCount字段设置为2,提升到特权级0时,CPUDemoStack2Seg复制了2个双字参数到DemoStack0Seg

从子程序SubRB返回时,CPL=0变换为CPL=2,堆栈也回到2级堆栈(DemoStack2Seg)。

4. 从演示任务切换到临时任务

演示任务采用段间转移指令JMP,通过任务门ToTempT切换到临时任务。演示任务的现场被保存到演示任务的TSS;临时任务的现场从临时任务的TSS恢复。

临时任务的挂起点是TempCodeSeg的“inc byte ptr es:[0h]”指令,所以恢复后的临时任务从该指令处开始执行。在恢复到临时任务时,SSDSFSGS被恢复为Normal_SelES被恢复为Video_Sel

5. 任务现场的保存、恢复

程序在临时任务和演示任务之间进行了多次任务切换。临时任务在进入时,清除屏幕内容,将屏幕左上角(0,0)处的字符设为’ 0’

演示任务执行一次,显示EDI的当前值。第1次执行时,EDI的值等于(80*4+50)*2,即000002E4h,在屏幕上位置(4,50)处显示“EDI=000002E 4 ,之后,EDI增加160,执行下一行。在切换到临时任务时,EDI的值被保存到DemoTSSSeg中。下一次从临时任务切换到演示任务时,EDIDemoTSSSeg中恢复,所以在屏幕上位置(5,50)处显示“EDI=00000384”。

从临时任务切换到演示任务时,临时任务的ECX值也被保存到TempTSSSeg中,切换回临时任务时,从TempTSSSeg恢复ECX值,所以,循环一共执行5次,每次将屏幕左上角(0,0)处的字符加1。执行结束时,该字符变为’ 5’

;程序清单: task.asm(任务切换)

INCLUDE         386SCD.INC

 

RDataSeg        SEGMENT PARA USE16              ;实方式数据段

                ;全局描述符表

GDT             LABEL   BYTE

                ;空描述符

DUMMY           Desc    <>

                ;规范段描述符

Normal          Desc    <0ffffh,,,ATDW,,>

                ;视频缓冲区段描述符(DPL=3)

VideoBuf        Desc    <0ffffh,8000h,0bh,ATDW+DPL3,,>

EFFGDT          LABEL   BYTE

                ;演示任务的局部描述符表段的描述符

DemoLDTab       Desc    <DemoLDTLen-1,DemoLDTSeg,,ATLDT,,>

                ;演示任务的任务状态段描述符

DemoTSS         Desc    <DemoTSSLen-1,DemoTSSSeg,,AT386TSS,,>

                ;临时任务的任务状态段描述符

TempTSS         Desc    <TempTSSLen-1,TempTSSSeg,,AT386TSS+DPL2,,>

                ;临时代码段描述符

TempCode        Desc    <0ffffh,TempCodeSeg,,ATCE,,>

                ;子程序代码段描述符

SubR            Desc    <SubRLen-1,SubRSeg,,ATCE,D32,>

GDNum           =       ($-EFFGDT)/8            ;需处理基地址的描述符个数

GDTLen          =       $-GDT                   ;全局描述符表长度

 

VGDTR           PDesc   <GDTLen-1,>             ;GDT伪描述符

SPVar           DW      ?                       ;用于保存实方式下的SP

<

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值