I'm recently playing with gnu-assembler in simple os development. I'm using code below to switch CPU to protected mode. In order to do this I set GDT as follow and performed far jump to given label wit 0x08 as GDT offset (to set CS). CPU did not reset itself after jmp, but none of mov instructions were executed correctly after jumping to leaveToKernel. The reason why Im saying that mov failed to set DS and SS is this 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]
Can someone help me understand and explain this behaviour? Thanks in advance
The code used to switch CPU to p-mode(GAS syntax):
.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