WEB开发网
开发学院软件开发汇编语言 汇编教程:控制转移(3) 阅读

汇编教程:控制转移(3)

 2009-10-12 09:36:41 来源:WEB开发网   
核心提示:<六>演示任务切换的实例(实例五)下面给出一个用于演示任务切换的实例,该实例的逻辑功能是在切换后显示原任务的挂起点(EIP)的值,汇编教程:控制转移(3)(3),该实例演示内容包括:直接通过TSS段的任务切换,通过任务门的任务切换,特权级0,(10)实模式下的数据和代码段,任务内特权级的变换及参数传递, 1

<六>演示任务切换的实例(实例五)


  下面给出一个用于演示任务切换的实例。该实例的逻辑功能是在切换后显示原任务的挂起点(EIP)的值。该实例演示内容包括:直接通过TSS段的任务切换,通过任务门的任务切换,任务内特权级的变换及参数传递。
 

1.实现步骤


  为了达到演示任务切换和特权级变换的目的,实例五在保护方式下涉及到两个任务,一个任务称为临时任务,另一个任务称为演示任务。演示任务的功能是演示通过调用门实现特权级的变换和堆栈间参数的自动复制。临时任务和演示任务配合展示任务切换。实例五的主要实现步骤如下:
   (1)实模式下初始化;
  (2)切换到保护模式;
  (3)设置TR对应临时任务,特权级为0;
  (4)直接切换到演示任务,演示任务的特权级为2;
  (5)把入口参数压入堆栈,经调用门进入显示信息子程序,显示信息子程序的特权级为0;
  (6)从堆栈中取出入口参数并处理;
  (7)从显示信息子程序返回特权级为2的演示代码段;
  (8)为切换回实模式作部分准备工作;
  (9)经任务门切换到特权级为0的临时任务;
  (10)准备返回实模式;
  (11)切换到实模式;
  (12)实模式下的恢复工作。
  在任务切换时,把原任务的现场保存到TR所指示的TSS内,然后再把指向目标任务的TSS描述符的选择子装入TR,所以在从临时任务切换到演示任务之前,要把指向临时任务TSS描述符的选择子装入TR。通过把演示任务的TSS初始化成恢复点在特权级2的代码段,使得从临时任务切换到演示任务后,当前特权级CPL=2。
 

2.源程序组织和清单


  实例五由如下部分组成:
  (1)全局描述符表GDT。GDT含有演示任务的TSS描述符和LDT段描述符,还含有临时任务TSS描述符和临时任务的代码段描述符,此外,还含有子程序代码段描述符、规范数据段描述符和视频缓冲区段描述符。
   (2)演示任务的TSS。以根据演示要求初始化。
  (3)演示任务的LDT段。它含有演示任务的0级和2级堆栈段描述符、代码段和数据段描述符、分别以数据段方式描述LDT和临时任务TSS的数据段描述符、以及指向子程序的调用门和指向临时任务的任务门。
   (4)演示任务的0级和2级堆栈段。32位段,特权级分别为0和2。
  (5)演示任务数据段。32位段,特权级3。
  (6)子程序代码段。32位代码段,特权级0。
  (7)演示任务代码段。32位代码段,特权级2。
  (8)临时任务的TSS段。未初始化。
  (9)临时任务代码段。16位代码段,特权级0。
  (10)实模式下的数据和代码段。
  该实例的逻辑功能是在切换后显示原任务的挂起点(EIP)的值。源程序清单如下:

;名称:ASM5.ASM
;功能:演示任务切换和任务内有特权级变换的转移
;编译:TASM ASM5.ASM
;链接:TLINK /32 ASM5.OBJ
;----------------------------------------------------------------------------
INCLUDE     386SCD.INC
;----------------------------------------------------------------------------
GDTSeg     SEGMENT PARA USE16        ;全局描述符表数据段(16位)
;----------------------------------------------------------------------------
        ;全局描述符表
GDT       LABEL  BYTE
        ;空描述符
DUMMY      Desc  <>
        ;规范段描述符及选择子
Normal     Desc  <0ffffh,,,ATDW,,>
Normal_Sel   =    Normal-GDT
        ;视频缓冲区段描述符(DPL=3)及选择子
VideoBuf    Desc  <0ffffh,8000h,0bh,ATDW+DPL3,,>
Video_Sel    =    VideoBuf-GDT
;----------------------------------------------------------------------------
EFFGDT     LABEL  BYTE
        ;演示任务的局部描述符表段的描述符及选择子
DemoLDTab    Desc  <DemoLDTLen-1,DemoLDTSeg,,ATLDT,,>
DemoLDT_Sel   =    DemoLDTab-GDT
        ;演示任务的任务状态段描述符及选择子
DemoTSS     Desc  <DemoTSSLen-1,DemoTSSSeg,,AT386TSS,,>
DemoTSS_Sel   =    DemoTSS-GDT
        ;临时任务的任务状态段描述符及选择子
TempTSS     Desc  <TempTSSLen-1,TempTSSSeg,,AT386TSS+DPL2,,>
TempTSS_Sel   =    TempTSS-GDT
        ;临时代码段描述符及选择子
TempCode    Desc  <0ffffh,TempCodeSeg,,ATCE,,>
TempCode_Sel  =    TempCode-GDT
        ;子程序代码段描述符及选择子
SubR      Desc  <SubRLen-1,SubRSeg,,ATCE,D32,>
SubR_Sel    =    SubR-GDT
;----------------------------------------------------------------------------
GDNum      =    ($-EFFGDT)/(SIZE Desc)  ;需处理基地址的描述符个数
GDTLen     =    $-GDT           ;全局描述符表长度
;----------------------------------------------------------------------------
GDTSeg     ENDS               ;全局描述符表段定义结束
;----------------------------------------------------------------------------
DemoLDTSeg   SEGMENT PARA USE16        ;局部描述符表数据段(16位)
;----------------------------------------------------------------------------
DemoLDT     LABEL  BYTE           ;局部描述符表
        ;0级堆栈段描述符(32位段)及选择子
DemoStack0   Desc  <DemoStack0Len-1,DemoStack0Seg,,ATDW,D32,>
DemoStack0_Sel =    DemoStack0-DemoLDT+TIL
        ;2级堆栈段描述符(32位段)及选择子
DemoStack2   Desc  <DemoStack2Len-1,DemoStack2Seg,,ATDW+DPL2,D32,>
DemoStack2_Sel =    DemoStack2-DemoLDT+TIL+RPL2
        ;演示任务代码段描述符(32位段,DPL=2)及选择子
DemoCode    Desc  <DemoCodeLen-1,DemoCodeSeg,,ATCE+DPL2,D32,>
DemoCode_Sel  =    DemoCode-DemoLDT+TIL+RPL2
        ;演示任务数据段描述符(32位段,DPL=3)及选择子
DemoData    Desc  <DemoDataLen-1,DemoDataSeg,,ATDW+DPL3,D32,>
DemoData_Sel  =    DemoData-DemoLDT+TIL
        ;把LDT作为普通数据段描述的描述符(DPL=2)及选择子
ToDLDT     Desc  <DemoLDTLen-1,DemoLDTSeg,,ATDW+DPL2,,>
ToDLDT_Sel   =    ToDLDT-DemoLDT+TIL
        ;把TSS作为普通数据段描述的描述符(DPL=2)及选择子
ToTTSS     Desc  <TempTSSLen-1,TempTSSSeg,,ATDW+DPL2,,>
ToTTSS_Sel   =    ToTTSS-DemoLDT+TIL
;----------------------------------------------------------------------------
DemoLDNum    =    ($-DemoLDT)/(SIZE Desc)  ;需处理基地址的LDT描述符数
;----------------------------------------------------------------------------
        ;指向子程序SubRB代码段的调用门(DPL=3)及选择子
ToSubR     Gate  <SubRB,SubR_Sel,,AT386CGate+DPL3,>
ToSubR_Sel   =    ToSubR-DemoLDT+TIL+RPL2
        ;指向临时任务Temp的任务门(DPL=3)及选择子
ToTempT     Gate  <,TempTSS_Sel,,ATTaskGate+DPL3,>
ToTempT_Sel   =    ToTempT-DemoLDT+TIL
;----------------------------------------------------------------------------
DemoLDTLen   =    $-DemoLDT
;----------------------------------------------------------------------------
DemoLDTSeg   ENDS               ;局部描述符表段定义结束
;----------------------------------------------------------------------------
DemoTSSSeg   SEGMENT PARA USE16        ;任务状态段TSS
;----------------------------------------------------------------------------
        DD   0             ;链接字
        DD   DemoStack0Len       ;0级堆栈指针
        DW   DemoStack0_Sel,0     ;0级堆栈选择子
        DD   0             ;1级堆栈指针(实例不使用)
        DW   0,0            ;1级堆栈选择子(实例不使用)
        DD   0             ;2级堆栈指针
        DW   0,0            ;2级堆栈选择子
        DD   0             ;CR3
        DW   DemoBegin,0        ;EIP
        DD   0             ;EFLAGS
        DD   0             ;EAX
        DD   0             ;ECX
        DD   0             ;EDX
        DD   0             ;EBX
        DD   DemoStack2Len       ;ESP
        DD   0             ;EBP
        DD   0             ;ESI
        DD   1986           ;EDI
        DW   Video_Sel,0        ;ES
        DW   DemoCode_Sel,0      ;CS
        DW   DemoStack2_Sel,0     ;SS
        DW   DemoData_Sel,0      ;DS
        DW   ToDLDT_Sel,0       ;FS
        DW   ToTTSS_Sel,0       ;GS
        DW   DemoLDT_Sel,0       ;LDTR
        DW   0             ;调试陷阱标志
        DW   $+2            ;指向I/O许可位图
        DB   0ffh           ;I/O许可位图结束标志
DemoTSSLen   =    $
;----------------------------------------------------------------------------
DemoTSSSeg   ENDS               ;任务状态段TSS结束
;----------------------------------------------------------------------------
DemoStack0Seg  SEGMENT PARA USE32        ;演示任务0级堆栈段(32位段)
DemoStack0Len  =    1024
        DB   DemoStack0Len DUP(0)
DemoStack0Seg  ENDS               ;演示任务0级堆栈段结束
;----------------------------------------------------------------------------
DemoStack2Seg  SEGMENT PARA USE32        ;演示任务2级堆栈段(32位段)
DemoStack2Len  =    512
        DB   DemoStack2Len DUP(0)
DemoStack2Seg  ENDS               ;演示任务2级堆栈段结束
;----------------------------------------------------------------------------
DemoDataSeg   SEGMENT PARA USE32        ;演示任务数据段(32位段)
Message     DB   'Value=',0
DemoDataLen   =    $
DemoDataSeg   ENDS               ;演示任务数据段结束
;----------------------------------------------------------------------------
SubRSeg     SEGMENT PARA USE32        ;子程序代码段(32位)
        ASSUME CS:SubRSeg
;----------------------------------------------------------------------------
SubRB      PROC  FAR
        push  ebp
        mov   ebp,esp
        pushad              ;保护现场
        mov   esi,DWORD PTR [ebp+12]  ;从0级栈中取出显示串偏移
        mov   ah,4ah          ;设置显示属性
        jmp   SHORT SubR2
SubR1:     stosw
SubR2:     lodsb
        or   al,al
        jnz   SubR1
        mov   ah,4eh          ;设置显示属性
        mov   edx,DWORD PTR [ebp+16]  ;从0级栈中取出显示值
        mov   ecx,8
SubR3:     rol   edx,4
        mov   al,dl
        call  HToASCII
        stosw
        loop  SubR3
        popad
        pop   ebp
        ret   8
SubRB      ENDP
;----------------------------------------------------------------------------
HToASCII    PROC
        and   al,0fh
        add   al,90h
        daa
        adc   al,40h
        daa
        ret
HToASCII    ENDP
;----------------------------------------------------------------------------
SubRLen     =    $
SubRSeg     ENDS               ;子程序代码段结束
;----------------------------------------------------------------------------
DemoCodeSeg   SEGMENT PARA USE32        ;演示任务的32位代码段
        ASSUME CS:DemoCodeSeg,DS:DemoDataSeg
;----------------------------------------------------------------------------
DemoBegin    PROC  FAR
        ;把要复制的参数个数置入调用门
        mov   BYTE PTR fs:ToSubR.DCount,2
        ;向2级堆栈中压入参数
        push  DWORD PTR gs:TempTask.TREIP
        push  OFFSET Message
        ;通过调用门调用SubRB
        CALL32 ToSubR_Sel,0
        ;把指向规范数据段描述符的选择子填入临时任务TSS
        ASSUME DS:TempTSSSeg
        push  gs
        pop   ds
        mov   ax,Normal_Sel
        mov   WORD PTR TempTask.TRDS,ax
        mov   WORD PTR TempTask.TRES,ax
        mov   WORD PTR TempTask.TRFS,ax
        mov   WORD PTR TempTask.TRGS,ax
        mov   WORD PTR TempTask.TRSS,ax
        ;通过任务门切换到临时任务
        JUMP32 ToTempT_Sel,0
         jmp   DemoBegin
DemoBegin    ENDP
DemoCodeLen   =    $
;----------------------------------------------------------------------------
DemoCodeSeg   ENDS               ;演示任务的32位代码段结束
;----------------------------------------------------------------------------
TempTSSSeg   SEGMENT PARA USE16        ;临时任务的任务状态段TSS
TempTask    TSS   <>
        DB   0ffh           ;I/O许可位图结束标志
TempTSSLen   =    $
TempTSSSeg   ENDS
;----------------------------------------------------------------------------
TempCodeSeg   SEGMENT PARA USE16        ;临时任务的代码段
        ASSUME CS:TempCodeSeg
;----------------------------------------------------------------------------
Virtual     PROC  FAR
        mov   ax,TempTSS_Sel      ;装载TR
        ltr   ax
        JUMP16 DemoTSS_Sel,0       ;直接切换到演示任务
        clts               ;清任务切换标志
        mov   eax,cr0          ;准备返回实模式
        and   al,11111110b
        mov   cr0,eax
        JUMP16 <SEG Real>,<OFFSET Real>
Virtual     ENDP
;----------------------------------------------------------------------------
TempCodeSeg   ENDS
;============================================================================
RDataSeg    SEGMENT PARA USE16        ;实方式数据段
VGDTR      PDesc  <GDTLen-1,>        ;GDT伪描述符
SPVar      DW   ?             ;用于保存实方式下的SP
SSVar      DW   ?             ;用于保存实方式下的SS
RDataSeg    ENDS
;----------------------------------------------------------------------------
RCodeSeg    SEGMENT PARA USE16
        ASSUME CS:RCodeSeg,DS:RDataSeg,ES:RDataSeg
;----------------------------------------------------------------------------
Start      PROC
        mov   ax,RDataSeg
        mov   ds,ax
        cld
        call  InitGDT          ;初始化全局描述符表GDT
        mov   ax,DemoLDTSeg
        mov   fs,ax
        mov   si,OFFSET DemoLDT
        mov   cx,DemoLDNum
        call  InitLDT          ;初始化局部描述符表LDT
        mov   SSVar,ss
        mov   SPVar,sp
        lgdt  QWORD PTR VGDTR      ;装载GDTR并切换到保护方式
        cli
        mov   eax,cr0
        or   al,1
        mov   cr0,eax
        JUMP16 <TempCode_Sel>,<OFFSET Virtual>
Real:      mov   ax,RDataSeg
        mov   ds,ax
        lss   sp,DWORD PTR SPVar    ;又回到实方式
        sti
        mov   ax,4c00h
        int   21h
Start      ENDP
;----------------------------------------------------------------------------
InitGDT     PROC
        push  ds
        mov   ax,GDTSeg
        mov   ds,ax
        mov   cx,GDNum
        mov   si,OFFSET EFFGDT
InitG:     mov   ax,[si].BaseL
        movzx  eax,ax
        shl   eax,4
        shld  edx,eax,16
        mov   WORD PTR [si].BaseL,ax
        mov   BYTE PTR [si].BaseM,dl
        mov   BYTE PTR [si].BaseH,dh
        add   si,SIZE Desc
        loop  InitG
        pop   ds
        mov   bx,16
        mov   ax,GDTSeg
        mul   bx
        mov   WORD PTR VGDTR.Base,ax
        mov   WORD PTR VGDTR.Base+2,dx
        ret
InitGDT     ENDP
;----------------------------------------------------------------------------
;入口参数:FS:SI=第一个要初始化的描述符,CX=要初始化的描述符数
;----------------------------------------------------------------------------
InitLDT     PROC
        mov   ax,WORD PTR fs:[si].BaseL
        movzx  eax,ax
        shl   eax,4
        shld  edx,eax,16
        mov   WORD PTR fs:[si].BaseL,ax
        mov   BYTE PTR fs:[si].BaseM,dl
        mov   BYTE PTR fs:[si].BaseH,dh
        add   si,SIZE Desc
        loop  InitLDT
        ret
InitLDT     ENDP
;----------------------------------------------------------------------------
RCodeSeg    ENDS
        END   Start

上一页  1 2 3 4  下一页

Tags:汇编 教程 控制

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接