The code snippet are switched. The one I state that works is the one that doesn't work. My apologies.
What I really wanted to understand is why I have to write the far jump instruction above the 32 bits directive to make it work (and not below, as I mistakenly implied)
Below are the contents of the original post for reference:
Hello, I am using nasm and I am having trouble understanding why the following code doesn't work:
Code: Select all
mov eax, cr0
or eax, 1
mov cr0, eax
jmp gdt_code-gdt_start:next_instruction ; jmp gdt_code-gdt_start:next_instruction --> jmp 0x08:next_instruction
bits 32
next_instruction:
Code: Select all
mov eax, cr0
or eax, 1
mov cr0, eax
bits 32
jmp gdt_code-gdt_start:next_instruction ; jmp gdt_code-gdt_start:next_instruction --> jmp 0x08:next_instruction
next_instruction:
This is how I have set up the global descriptor table:
Code: Select all
gdt_start:
gdt_null:
dq 0
gdt_code:
dw 0xFFFF ; Segment Limit 15:00
dw 0x0000 ; Base Address 15:00
db 0x00 ; Base Address 23:16
; Present Privilege Descriptor type Executable Conforming Readable Accessed
db 0b1__________00______________1___________________1_______________0_______________1___________0
; Granularity 32 bits 64 bits Available Segment Limit 19:16
db 0b1______________1___________0___________0___________1111
db 0x00 ; Base 31:24
gdt_data:
dw 0xFFFF ; Segment Limit 15:00
dw 0x0000 ; Base Address 15:00
db 0x00 ; Base Address 23:16
; Present Privilege Descriptor type Executable Expansion-direction Write-enable Accessed
db 0b1___________00_____________1___________________0_______________0_______________________1_______________0
; Granularity 32 bits 64 bits Available Segment Limit 19:16
db 0b1______________1___________0___________0___________1111
db 0x00 ; Base 31:24
gdt_end:
gdtr_start:
dw gdt_end - gdt_start - 1 ; limit (Size of GDT - 1)
dd gdt_start
Thanks for your support.