从实模式到保护模式出现错误
org 07c00hjmp main
gdt_null:
dd 0
dd 0
gdt_code_addr equ $ - gdt_null ; 求得代码段在GDT表中的位置
gdt_code:
dw 0ffffh ; 段大小为4GB
dw 0 ; 基地址(24位)
db 0
db 10011010b ; 属性描述位,指明此是代码段,可读可执行
db 11001111b ; 具体的每一位是代表什么可查Intel CPU编程手册
db 0
gdt_data_addr equ $ - gdt_null ; 求得数据段在GDT表中的位置
gdt_data:
dw 0ffffh
dw 0
db 0
db 10010010b ; 指明此是数据段,可读可写
db 11001111b
db 0
gdt_addr:
dw gdt_addr - gdt_null - 1 ; GDT 表的大小
dd gdt_null ; GDT 表的位置
; ---------------------------------------------------------------------------
main: ; 引导程序从此处开始执行
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov sp,0100h
lgdt ; 载入 GDT 的描述符
;关中断
cli
;打开地址A20
in al,92h
or al,00000010b
out 92h,al
mov eax , cr0 ; 下面三句设置 cr0 的第 0 位(PE位)为1,
; 表示进入保护模式
or eax , 1
mov cr0 , eax
jmp gdt_code_addr:code_32 ; 跳入32位的代码段中
code_32:
mov ax , gdt_data_addr ; 以下三句设置 DS,ES,SS,FS,GS
; 为数据段描述表的位置
times 510-($-$$) db 0
dw 0xaa55;结束标志
哪里错了 上面是我在你的基础上改的,说实话,不建议把段的描述符直接定义在数据中,应该自己写个子过程,在里面计算描述符,这样代码可读性强点。不好意思,上次看错代码了。你的代码段选择子放的位置是对的,不过还是不建议你这样写,应该在代码中计算出来,因为是ring0级的所以没问题,如果是用户层ring3的就有问题了 实在是太高深了,我还没有学到这一步,正在实验七中徘徊,帮你顶了 还没能开明白 本帖最后由 小名明SIU 于 2013-9-3 13:12 编辑
对你的代码只有一个评价:乱。
这些问题调试一下就知道了。
dw gdt_addr - gdt_null - 1 ; GDT 表的大小
错了,应该是dw gdt_addr - gdt_null,不要减一,不信找个特殊的减减试试。
小名明SIU 发表于 2013-8-30 23:59 static/image/common/back.gif
对你的代码只有一个评价:乱。
这些问题调试一下就知道了。
dw gdt_addr - gdt_null - 1 ; GDT 表的大小...
还是不明白能不能告诉我放在哪个位置 放在第一个描述符和第二个描述符之间 我劝你还是学会怎么调试吧 觉得好就采纳一下啊 小名明SIU 发表于 2013-9-1 11:39 static/image/common/back.gif
觉得好就采纳一下啊
{:5_100:}能不能把代码修改后 给我 org 07c00h
jmp main
gdt_null:
dd 0
dd 0
gdt_code_addr equ $ - gdt_null ; 求得代码段在GDT表中的位置
gdt_code:
dw 0ffffh ; 段大小为4GB
dw 0 ; 基地址(24位)
db 0
db 10011010b ; 属性描述位,指明此是代码段,可读可执行
db 11001111b ; 具体的每一位是代表什么可查Intel CPU编程手册
db 0
gdt_data_addr equ $ - gdt_null ; 求得数据段在GDT表中的位置
gdt_data:
dw 0ffffh
dw 0
db 0
db 10010010b ; 指明此是数据段,可读可写
db 11001111b
db 0
gdt_addr:
dw gdt_addr - gdt_null; GDT 表的大小
dd gdt_null ; GDT 表的位置
; ---------------------------------------------------------------------------
main: ; 引导程序从此处开始执行
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov sp,0100h
lgdt ; 载入 GDT 的描述符
;关中断
cli
;打开地址A20
in al,92h
or al,00000010b
out 92h,al
mov eax , cr0 ; 下面三句设置 cr0 的第 0 位(PE位)为1,
; 表示进入保护模式
or eax , 1
mov cr0 , eax
jmp gdt_code_addr:code_32 ; 跳入32位的代码段中
code_32:
mov ax , gdt_data_addr ; 以下三句设置 DS,ES,SS,FS,GS
; 为数据段描述表的位置
times 510-($-$$) db 0
dw 0xaa55;结束标志 本帖最后由 小名明SIU 于 2021-3-22 18:48 编辑
如果不知道怎么调试,或者想学习一些保护模式的知识,虽然我知道的也不多,但是我会尽量帮你解答,还是推荐使用《X86从实模式到保护模式》
页:
[1]