📄 asm5.asm
字号:
;名称: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 <SubRLen16-1,SubRSeg,,ATCE,D32,>
;这句改过原版是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 <DemoCodeLen16-1,DemoCodeSeg,,ATCE+DPL2,D32,>
;以上这句改过,原版是DemoCode Desc <DemoCodeLen-1,DemoCodeSeg,,ATCE+DPL2,D32,>
DemoCode_Sel = DemoCode-DemoLDT+TIL+RPL2
;演示任务数据段描述符(32位段,DPL=3)及选择子
DemoData Desc <DemoDataLen16-1,DemoDataSeg,,ATDW+DPL3,D32,>
;以上这句改过,原版是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 <SubRB16,SubR_Sel,,AT386CGate+DPL3,>
;以上这句改过,原版是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 DemoBegin16,0 ;这一句改过,原版是DW DemoBegin,0
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 = $
DemoDataLen16 = WORD PTR 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -