保护模式,设置段寄存器

时间:2015-05-15 22:56:11

标签: assembly operating-system gas protected-mode

我最近在简单的os开发中使用gnu-assembler。我使用下面的代码将CPU切换到保护模式。为了做到这一点,我将GDT设置为跟随并执行远远跳转到给定标签0x08作为GDT偏移(设置CS)。在jmp之后,CPU没有重置自身,但跳转到mov后没有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 $1, %eax
    mov %eax, %cr0
    jmp $0x08 ,$leaveToKernel
    leaveToKernel:
    xor %eax, %eax
    mov $0x10, %ax
    mov %ax, %ss
    mov %ax, %ds
    hlt
leave    
ret

1 个答案:

答案 0 :(得分:1)

显然你的CS基础不是零所以我说你没有跳到正确的位置。拥有非零CS基数并不常见,我假设您确实想要0,但设置GDT条目错误。解决它:)