本人在学习保护模式, 学调用门的时候, 代码出了点问题 , 不会调试,请帮忙看看.
代码是用fasm写的,在DOS下运行的.btw, 问一下DOS下用什么调试工具 ? debug对保护模式完全无能啊,谢谢!!
include 'pm.inc'
org 100h
jmp LABEL_BEGIN
LABEL_GDT: Descriptor 0,0,0
LABEL_DESC_NORMAL: Descriptor 0,0ffffh,DA_DRW
LABEL_DESC_CODE32: Descriptor 0,SegCode32Len-1,DA_C+DA_32
LABEL_DESC_CODE16: Descriptor 0,0ffffh,DA_C
LABEL_DESC_CODE_DEST:Descriptor 0,SegCodeDestLen-1,DA_C+DA_32
LABEL_DESC_CODE_RING3:Descriptor 0,SegCodeRing3Len-1,DA_C+DA_32+DA_DPL3
LABEL_DESC_DATA: Descriptor 0,DataLen-1,DA_DRW
LABEL_DESC_STACK: Descriptor 0,TopOfStack,DA_DRWA+DA_32
LABEL_DESC_STACK3: Descriptor 0,TopOfStack3,DA_DRWA+DA_32+DA_DPL3
LABEL_DESC_TSS: Descriptor 0,TSSLen-1,DA_386TSS
LABEL_DESC_VIDEO: Descriptor 0b8000h,0ffffh,DA_DRW+DA_DPL3
LABEL_CALL_GATE_TEST: Gate SelectorCodeDest,0,0,DA_386CGate+DA_DPL3
GdtLen = $-LABEL_GDT
GdtPtr dw GdtLen-1
dd 0
SelectorNormal = LABEL_DESC_NORMAL-LABEL_GDT
SelectorCode32 = LABEL_DESC_CODE32-LABEL_GDT
SelectorCode16 = LABEL_DESC_CODE16-LABEL_GDT
SelectorCodeDest = LABEL_DESC_CODE_DEST-LABEL_GDT
SelectorCodeRing3 = LABEL_DESC_CODE_RING3-LABEL_GDT+SA_RPL3
SelectorData = LABEL_DESC_DATA-LABEL_GDT
SelectorStack = LABEL_DESC_STACK-LABEL_GDT
SelectorStack3 = LABEL_DESC_STACK3-LABEL_GDT+SA_RPL3
SelectorTSS = LABEL_DESC_TSS-LABEL_GDT
SelectorVideo = LABEL_DESC_VIDEO-LABEL_GDT
SelectorCallGateTest = LABEL_CALL_GATE_TEST-LABEL_GDT+SA_RPL3
use32
LABEL_DATA:
SPValueInRealMode dw 0
PMMessage: db 'In Protect Mode now.^_^',0
OffsetPMMessage = PMMessage-LABEL_DATA
DataLen = $-LABEL_DATA
LABEL_STACK:
times 512 db 0
TopOfStack = $-LABEL_STACK-1
LABEL_STACK3: ;ring3堆栈段
times 512 db 0
TopOfStack3 = $-LABEL_STACK3-1
LABEL_TSS:
dd 0 ;back
dd TopOfStack ;0级堆栈
dd SelectorStack ;
dd 0 ;1级堆栈
dd 0 ;
dd 0 ;2级堆栈
dd 0 ;
dd 0 ;cr3
dd 0 ;eip
dd 0 ;eflags
dd 0 ;eax
dd 0 ;ecx
dd 0 ;edx
dd 0 ;ebx
dd 0 ;esp
dd 0 ;ebp
dd 0 ;esi
dd 0 ;edi
dd 0 ;es
dd 0 ;cs
dd 0 ;ss
dd 0 ;ds
dd 0 ;fs
dd 0 ;gs
dd 0 ;ldt
dw 0 ;调试陷阱标志
dw $-LABEL_TSS+2 ;I/O位图基址
db 0ffh ;I/O位图结束标志
TSSLen = $-LABEL_TSS
use16
LABEL_BEGIN:
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov sp,0100h
mov [LABEL_GO_BACK_TO_REAL+3],ax
mov [SPValueInRealMode],sp
InitDescriptor LABEL_SEG_CODE16,LABEL_DESC_CODE16
InitDescriptor LABEL_SEG_CODE32,LABEL_DESC_CODE32
InitDescriptor LABEL_SEG_CODE_DEST,LABEL_DESC_CODE_DEST
InitDescriptor LABEL_DATA,LABEL_DESC_DATA
InitDescriptor LABEL_STACK,LABEL_DESC_STACK
InitDescriptor LABEL_STACK3,LABEL_DESC_STACK3
InitDescriptor LABEL_CODE_RING3,LABEL_DESC_CODE_RING3
InitDescriptor LABEL_TSS,LABEL_DESC_TSS
xor eax,eax
mov ax,ds
shl eax,4
add eax,LABEL_GDT
mov dword [GdtPtr+2],eax
lgdt fword [GdtPtr]
cli
EnableA20
EnablePM
jmp dword SelectorCode32:0
LABEL_REAL_ENTRY:
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov sp,[SPValueInRealMode]
DisableA20
sti
mov ax,4c00h
int 21h
use32
LABEL_SEG_CODE32:
mov ax,SelectorData
mov ds,ax
mov ax,SelectorVideo
mov gs,ax
mov ax,SelectorStack
mov ss,ax
mov esp,TopOfStack
;下面显示一个字符串
mov ah,0abh
mov esi,OffsetPMMessage
mov edi,(80*10+0)*2
cld
.1:
lodsb
or al,al
jz .2
gs mov word [edi],ax
add edi,2
jmp .1
.2:
call DispReturn
;Load TSS
mov ax,SelectorTSS
ltr ax
push SelectorStack3
push TopOfStack3
push SelectorCodeRing3
push 0
retf ;ring0 -> ring3
DispReturn:
push eax
push ebx
mov eax,edi
mov bl,160
div bl
and eax,0ffh
inc eax
mul bl
mov edi,eax
pop ebx
pop eax
ret
SegCode32Len = $-LABEL_SEG_CODE32
use16
LABEL_SEG_CODE16:
mov ax,SelectorNormal
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
DisablePM
LABEL_GO_BACK_TO_REAL:
jmp 0:LABEL_REAL_ENTRY
Code16Len = $-LABEL_SEG_CODE16
use32
LABEL_SEG_CODE_DEST:
mov ax,SelectorVideo
mov gs,ax
mov edi,(80*12+0)*2
mov ah,0bch
mov al,'C'
gs mov word [edi],ax
retf
SegCodeDestLen = $-LABEL_SEG_CODE_DEST
use32
LABEL_CODE_RING3:
mov ax,SelectorVideo
mov gs,ax
mov edi,(80*14+0)*2
mov ah,0bch
mov al,'3'
gs mov word [edi],ax
;[COLOR="Red"]已经定位是下面的call调用门有问题,但是具体是什么问题不清楚,求解决[/COLOR]
call SelectorCallGateTest:0 ;测试调用门(有特权级变换)
jmp SelectorCode16:0
SegCodeRing3Len = $-LABEL_CODE_RING3
pm.inc文件
;descriptor
;usage:Descriptor Base,Limit,Attr
; Base: dd
; Limit: dd
; Attr: dw
macro Descriptor Base,Limit,Attr
{
dw Limit and 0ffffh
dw Base and 0ffffh
db (Base shr 16) and 0ffh
dw ((Limit shr 8) and 0f00h) or (Attr and 0f0ffh)
db (Base shr 24) and 0ffh
}
macro Gate Selector,Offset,DCount,Attr
{
dw Offset and 0ffffh
dw Selector
dw (DCount and 1fh) or ((Attr shl 8) and 0ff00h)
dw ((Offset shr 16) and 0ffffh)
}
DA_C equ 98h
DA_CR equ 9Ah
DA_32 equ 4000h
DA_DRW equ 92h
DA_386CGate equ 8ch
DA_386IGate equ 8eh
DA_386TGate equ 0xef
DA_LIMIT_4K equ 8000h
DA_DRWA equ 93h
DA_386TSS equ 89h
DA_LDT equ 82h
SA_TIL equ 04h
DA_DPL3 equ 60h
SA_RPL3 equ 3
;初始化GDT中的描述符,参数为:段起始偏移地址,段描述符偏移地址
macro InitDescriptor TheLabel,TheDescriptor
{
push eax
xor eax,eax
mov ax,cs
shl eax,4
add eax,TheLabel
mov word [TheDescriptor+2],ax
shr eax,16
mov byte [TheDescriptor+4],al
mov byte [TheDescriptor+7],ah
pop eax
}
;打开A20
macro EnableA20
{
push ax
in al,92h
bts ax,1
out 92h,al
pop ax
}
;关闭A20
macro DisableA20
{
push ax
in al,92h
btr ax,1
out 92h,al
pop ax
}
;打开保护模式
macro EnablePM
{
push eax
mov cr0,eax
bts ax,0
mov eax,cr0
pop eax
}
;关闭保护模式
macro DisablePM
{
push eax
mov cr0,eax
btr ax,0
mov eax,cr0
pop eax
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!