| ;堆栈指针送BP
push eax
push ebx ;保存EAX、EBX
;在V86堆栈顶形成返回点的现场
mov ax,VAllMem_Sel ;转载描述最低1M字节线性地址
mov ds,ax ; 空间的描述符选择子
xor eax,eax
mov ax,Psp ;修改在V86任务0级堆栈中保存
sub ax,3*2 ; 的3级堆栈的指针,减3个字
mov Psp,ax ; 即在栈顶空出3个字
xor ebx,ebx
mov bx,Pss ;使EBX指向V86堆栈顶
shl ebx,4
add ebx,eax
mov ax,Pip ;把保存在0级堆栈中的返回地址
mov WORD PTR [ebx],ax ;的偏移部分送V86堆栈
mov ax,Pcs
mov WORD PTR [ebx+2],ax ;段值部分送V86堆栈
mov ax,Pflag
mov WORD PTR [ebx+4],ax ;标志值送V86堆栈
;用对应的中断向量值代替返回地址
mov bx,[bp] ;取中断向量号
shl bx,2 ;乘4
mov ax,[bx] ;取实模式下对应中断向量的偏移
mov Pip,ax ;代替0级堆栈中的EIP
mov ax,[bx+2] ;取实模式下对应中断向量的段值
mov Pcs,ax ;代替0级堆栈中的CS
pop ebx ;恢复现场
pop eax
pop bp
pop bp
;从保护方式返回V86方式
;先转入对应的中断处理程序,再返回中断发生处
iretd
TPBegin ENDP
;----------------------------------------------------------------------------
TPCodeLen = $
TPCodeSeg ENDS
;============================================================================
;V86任务下的通用保护故障处理程序代码段
;----------------------------------------------------------------------------
GPCodeSeg SEGMENT PARA USE32
ASSUME CS:GPCodeSeg
;----------------------------------------------------------------------------
GPBegin PROC FAR
mov ax,V86Data_Sel
mov ds,ax
mov si,OFFSET GPErrMess
mov ax,Video_Sel
mov es,ax
mov di,0
mov ah,17h
mov cx,GPErrMessLen
cld
GNext: lodsb
stosw
loop GNext
add esp,4
mov ax,4c01h
JUMP16 TPCode_Sel,Ent21H
GPBegin ENDP
;----------------------------------------------------------------------------
GPCodeLen = $
GPCodeSeg ENDS
;============================================================================
;V86方式执行的8086程序段
V86CodeSeg SEGMENT PARA USE16
ASSUME CS:V86CodeSeg,DS:V86CodeSeg
Message DB 'V86 is OK!',0dh,0ah,24h
V86Begin PROC FAR
mov ah,9
mov dx,OFFSET Message
int 21h
mov ax,RCodeSeg
sub ax,GDTSeg
mov dx,OFFSET TSRLine+15
shr dx,4
add dx,ax
add dx,10h
mov ax,3100h
int 21h
V86Begin ENDP
V86CodeSeg ENDS
;============================================================================
TempTSSSeg SEGMENT PARA USE16 ;临时任务的TSS段
TSS <>
DB 0ffh ;I/O许可位图结束标志
TempTSSLen = $
TempTSSSeg ENDS
;============================================================================
TempCodeSeg SEGMENT PARA USE16 ;临时任务的代码段
ASSUME CS:TempCodeSeg
;----------------------------------------------------------------------------
Virtual PROC FAR
mov ax,Normal_Sel
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov ax,TempTSS_Sel ;装载TR
ltr ax
JUMP16 V86TSS_Sel,0 ;直接切换到演示任务
ToDos: clts
mov eax,cr0 ;准备返回实模式
and al,11111110b
mov cr0,eax
JUMP16 <SEG Real>,<OFFSET Real>
Virtual ENDP
;----------------------------------------------------------------------------
TempCodeSeg ENDS
;============================================================================
RDataSeg SEGMENT PARA USE16 ;实方式数据段
RDataSeg ENDS
;============================================================================
RCodeSeg SEGMENT PARA USE16
ASSUME CS:RCodeSeg, 上一页 [1] [2] [3] [4] [5] [6] 下一页 |