保护模式,设置段寄存器
Protected mode, setting segment registers
我最近在简单 os 开发中使用 gnu-assembler。我正在使用下面的代码将 CPU 切换到保护模式。为了做到这一点,我将 GDT 设置如下,并执行远跳到给定标签机智 0x08 作为 GDT 偏移量(设置 CS)。 CPU 在 jmp
之后没有自行重置,但是 mov
条指令中的 none 条在跳转到 leaveToKernel
后正确执行。我说 mov
设置 DS 和 SS 失败的原因是这个 qemu print (info registers
):
EAX=00000000 EBX=00105fd8 ECX=000003eb EDX=000b8000
ESI=00010000 EDI=00000000 EBP=00105fc0 ESP=00105fc0
EIP=0083ec44 EFL=00200002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 00100000 02710fff 00c09a00 DPL=0 CS32 [-R-]
SS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
有人可以帮助我理解和解释这种行为吗?提前致谢
用于将CPU切换到p模式的代码(GAS语法):
.equ NULL_DESCRIPTOR, 0x0000000000000000
.equ CODE0, 0x00C09A1000002710
.equ DATA0, 0x00C09210010007D0
.equ PLACE_HLD1, 0x0000000000000000
.equ PLACE_HLD2, 0x0000000000000000
.section .data
GDT:
.quad NULL_DESCRIPTOR
.quad CODE_P0
.quad DATA_P0
.quad PLACE_HLD1
.quad PLACE_HLD2
_GDT:
.word 24
.long GDT
.section .text
.global setProtectedMode
.type setProtectedMode, @function
setProtectedMode:
push %ebp
mov %esp,%ebp
cli
lgdt _GDT
mov %cr0, %eax
or , %eax
mov %eax, %cr0
jmp [=11=]x08 ,$leaveToKernel
leaveToKernel:
xor %eax, %eax
mov [=11=]x10, %ax
mov %ax, %ss
mov %ax, %ds
hlt
leave
ret
显然你的 CS 基础不是零所以我说你没有跳到正确的地方。具有非零 CS 基础的情况并不常见,我假设您确实想要 0,但设置了错误的 GDT 条目。修复它:)
我最近在简单 os 开发中使用 gnu-assembler。我正在使用下面的代码将 CPU 切换到保护模式。为了做到这一点,我将 GDT 设置如下,并执行远跳到给定标签机智 0x08 作为 GDT 偏移量(设置 CS)。 CPU 在 jmp
之后没有自行重置,但是 mov
条指令中的 none 条在跳转到 leaveToKernel
后正确执行。我说 mov
设置 DS 和 SS 失败的原因是这个 qemu print (info registers
):
EAX=00000000 EBX=00105fd8 ECX=000003eb EDX=000b8000
ESI=00010000 EDI=00000000 EBP=00105fc0 ESP=00105fc0
EIP=0083ec44 EFL=00200002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 00100000 02710fff 00c09a00 DPL=0 CS32 [-R-]
SS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
有人可以帮助我理解和解释这种行为吗?提前致谢
用于将CPU切换到p模式的代码(GAS语法):
.equ NULL_DESCRIPTOR, 0x0000000000000000
.equ CODE0, 0x00C09A1000002710
.equ DATA0, 0x00C09210010007D0
.equ PLACE_HLD1, 0x0000000000000000
.equ PLACE_HLD2, 0x0000000000000000
.section .data
GDT:
.quad NULL_DESCRIPTOR
.quad CODE_P0
.quad DATA_P0
.quad PLACE_HLD1
.quad PLACE_HLD2
_GDT:
.word 24
.long GDT
.section .text
.global setProtectedMode
.type setProtectedMode, @function
setProtectedMode:
push %ebp
mov %esp,%ebp
cli
lgdt _GDT
mov %cr0, %eax
or , %eax
mov %eax, %cr0
jmp [=11=]x08 ,$leaveToKernel
leaveToKernel:
xor %eax, %eax
mov [=11=]x10, %ax
mov %ax, %ss
mov %ax, %ds
hlt
leave
ret
显然你的 CS 基础不是零所以我说你没有跳到正确的地方。具有非零 CS 基础的情况并不常见,我假设您确实想要 0,但设置了错误的 GDT 条目。修复它:)