📄 asm5.asm
字号:
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -