哪位达人玩过80X86特权转换的
bochsdbg 报#TS #GP #DF #GP 错怎么回事
%include "pm.inc"
org 07c00h
jmp begin
db 11h
;初始化GDT
label_gdt:Descriptor 0,0,0 ;空描述符
label_code32:Descriptor 0,0ffffh,DA_C+DA_32 ;0级代码段
label_code32d:Descriptor 0,0ffffh,DA_C+DA_32 ;3级
label_data:Descriptor 0b8000h,0ffffh,DA_DRW+DA_DPL3 ;3级
label_ldt:Descriptor 0,0ffffh,DA_LDT ;LDT
label_ss0:Descriptor 0,ss0len, DA_DRWA + DA_32 ;SS0堆栈
label_ss3:Descriptor 0,ss3len, DA_DRWA + DA_32 + DA_DPL3 ;SS3堆栈
label_gate:Gate selectorcode,0,0,DA_386CGate ;0级门
label_gate2:Gate selectorcode2,0,0,DA_386CGate+DA_DPL3 ;3级门
label_tss:Descriptor 0,TSSLen-1,DA_386TSS ;TSS描述符
gdtlen equ $-label_gdt ;GDT长度
;段选择子
selectorcode equ label_code32-label_gdt
selectordata equ label_data - label_gdt+SA_RPL3
selectorldt equ label_ldt-label_gdt
selectorss0 equ label_ss0-label_gdt
selectorss3 equ label_ss3-label_gdt+SA_RPL3
selectorgate equ label_gate-label_gdt+SA_RPL3
selectorTSS equ label_tss-label_gdt
selectorgate2 equ label_gate2-label_gdt+SA_RPL3
selectorcode2 equ label_code32d - label_gdt
;GDT长度 界限 基址
vggdtr dw gdtlen-1
dd 0
;LDT
ldt:
label_codec32:Descriptor 0,0ffffh,DA_C + DA_32 + DA_DPL3 ;3级代码段CODEC32
selectorcodec32 equ label_codec32-ldt+4+3 ;选择子
;TSS段
LABEL_TSS:
DD0; Back
DDss0len; 0 级堆栈
DDselectorss0;
DD0; 1 级堆栈
DD0;
DD0; 2 级堆栈
DD0;
DD0; CR3
DD0; EIP
DD0; EFLAGS
DD0; EAX
DD0; ECX
DD0; EDX
DD0; EBX
DD0; ESP
DD0; EBP
DD0; ESI
DD0; EDI
DD0; ES
DD0; CS
DD0; SS
DD0; DS
DD0; FS
DD0; GS
DD0; LDT
DW0
tss1:DW $+2; 调试陷阱标志
DB 0ffh ; I/O位图基址
; I/O位图结束标志
TSSLenequ$ - LABEL_TSS
;0级堆栈段
ss0:dd 0
dd 0
dd 0
dd 0
dd 0
db 0
ss0len equ $-ss0-1
;3级堆栈段
ss3:dd 0
dd 0
dd 0
dd 0
dd 0
db 0
ss3len equ $-ss3-1
;程序入口点
begin:
;初始化0级代码段
mov ax,0
mov ds,ax
mov ax,[tss1]
mov ax,code32
mov [label_code32+2],ax
;初始化SS0堆栈段
mov ax,ss0
mov [label_ss0+2],ax
;初始化SS0堆栈段
mov ax,ss3
mov [label_ss3+2],ax
;初始化LDT
mov ax,ldt
mov [label_ldt+2],ax
;初始化代码段
mov ax,code32d
mov [label_code32d+2],ax
;初始化代码段
mov ax,codec32
mov [label_codec32+2],ax
;初始化TSS段
xoreax, eax
movax, ds
shleax, 4
addeax, label_tss
movword [label_tss + 2], ax
shreax, 16
movbyte [label_tss + 4], al
movbyte [label_tss + 7], ah
;初始化GDT
mov eax,label_gdt
mov [vggdtr+0x02],eax
;加载GDT
lgdt [vggdtr]
;打开A20
cli
in al,92h
or al,2
out 92h,al
;准备进入保护模式
mov eax,cr0
or eax,1
mov cr0,eax
;JMP到标号CODE32 正常
jmp selectorcode:0
real:
[bits 32]
mov ax,0b800h
mov ds,ax
mov bx,80*10*2+4
mov ax,0c63h
mov [bx],ax
in al,92h
and al,0fdh
out 92h,al
jmp $
[bits 32]
code32d:
mov ax,0dh
mov ax,0dh
mov ax,0dh
jmp $
[bits 32]
code32:
mov ax,selectorss0
mov ss,ax
mov sp,ss0len
mov ax,selectordata
mov ds,ax
mov ax,0c61h
mov bx,80*10*2
mov [bx],ax
mov ax,selectorldt
lldt ax
movax, selectorTSS
ltrax
;跳到LDT里的CODEC32段 标号CODEC32 正常
push dword selectorss3
push dword ss3len
push dword selectorcodec32
push dword 0
retf
code32m:
mov eax,cr0
and eax,0fffffffeh
mov cr0,eax
jmp 0:real
[bits 32]
codec32:
mov ax,selectordata ;正常
mov ds,ax ;正常
mov ax,0c62h ;正常
mov bx,80*10*2+2 ;正常
mov [bx],ax ;正常
call selectorgate2:0 ;出错 这句是关键跳到3级selectrocode2可以跳到0级selectorcode好像就 ;不行了 不知道哪错了
jmp $
times 510-($-$$) db 0
dw 0xaa55
[解决办法]
80X86汇编语言程序设计教程(杨季文)的第10章有详细讲解,你可以参照里面内容来修改上面错误的代码。
[解决办法]
杨季文的80x86汇编第10章就是说保护模式的