谁能解决一下特权的代码
BOCHSDBG 报错 网址 hiphotos.baidu.com/zhidao/pic/item/8d5494ee3f29f5b82df534ac.jpg
%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
[解决办法]
我看你挺执著啊,总是发帖求助。可我时间有限,没工夫分析你的代码。这样,咱俩互相配合着把你的问题搞定,如何?
第一步,先把描述符表建好。不要用什么宏,直接用32位数字。像这样:
;不要用org 0x7c00,使用偏移地址的地方,一律加0x7c00jmp begin;以下建立GDT;描述符#0,空描述符gdt_00 dd 0x00000000,0x00000000 ;描述符#1,保护模式下的代码段,基地址0x00007c00,界限0x200,粒度为字节gdt_01 dd 0x7c000200,0x00409800;请在后面补充其它描述符,补充完成后,帖在下面,我来看看,然后告诉你怎么做。
[解决办法]
还有啊,不要乱用标号,乱七八糟的,除了你,谁看得明白,谁记得住啊。再说,如果单纯自己用,根据不需要,哪个描述符在GDT的几号槽位,你还记不住吗?所以,下面的伪指令equ去掉吧。
;段选择子selectorcode equ label_code32-label_gdtselectordata equ label_data - label_gdt+SA_RPL3selectorldt equ label_ldt-label_gdtselectorss0 equ label_ss0-label_gdtselectorss3 equ label_ss3-label_gdt+SA_RPL3 selectorgate equ label_gate-label_gdt+SA_RPL3selectorTSS equ label_tss-label_gdtselectorgate2 equ label_gate2-label_gdt+SA_RPL3selectorcode2 equ label_code32d - label_gdt
[解决办法]
不好意思,弄错了。这个真不能去掉:
;GDT长度 界限 基址vggdtr dw gdtlen-1 dd 0
[解决办法]
这厮,何还不来乎?
这样吧,你将你的思路和具体的实现过程说一说,我来帮你重新写代码吧。一定要详细哟~
[解决办法]
咋还同时发帖了涅!你等我,我好好看看。马上就回来。
[解决办法]
以下是经我整理过的代码,改正了你的一些错误:
jmp begin;----------------------------------------;以下建立GDT;空描述符gdt_00 dd 0x00000000,0x00000000;ring0代码段,32位,基址0x00000000,界限0x0ffff,字节粒度,DPL=00gdt_01 dd 0x0000ffff,0x00409800;ring3代码段,32位,基址0x00000000,界限0x0ffff,字节粒度,DPL=11gdt_02 dd 0x0000ffff,0x0040f800;ring3的TSS段,基址0x00000000,界限0x00000,字节粒度,386-TSS,DPL=11gdt_03 dd 0x00000000,0x0000e900;门描述符gdt_04 dd 0x00000000,0x00008c00;ring0的堆栈,32位,基址0x00000000,界限0x00000,字节粒度,DPL=00gdt_05 dd 0x00000000,0x00409600;ring3的堆栈,32位,基址0x00000000,界限0x00000,字节粒度,DPL=00gdt_06 dd 0X00000000,0x0040f600;----------------------------------------vggdtr dw gdt_06-gdt_00 dd 0;----------------------------------------;ring0的堆栈ss0: times 20 db 0;ring3的堆栈ss3: times 20 db 0;ring3的TSS段tss3: times 104 db 0;----------------------------------------begin:
[解决办法]
暂时发现,你的调用门特权级为00,这是不对的。调用门的DPL表示可以访问此门的程序的特权级。所以,应当改成11。
;指向ring0代码的调用门,选择器0x0000,偏移地址0x0000,无参数,DPL=11 gdt_04 dd 0x00000000,0x0000ec00