Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
drnono
Posts: 23 Joined: Sun Aug 09, 2015 11:54 am
Post
by drnono » Sun Nov 18, 2018 11:23 am
Hi. My code doesn't survive the jump to protected mode - it just crashes and resets. I've tried for ages to get this to work. I can't see whats wrong with the code either. Any ideas?
Code: Select all
start:
mov ax, 0x7c0
mov es, ax
mov ds, ax
xor eax,eax
mov ax,ds ; get linear/physical address for gdt, ie 16*ds + gdt
shl eax, 4 ; *16
add eax, GDT
mov [GDTR+2], eax ; GDTR - contains gdt offset
cli
lgdt [GDTR]
mov eax, cr0
or eax,1 ; set protection enable in control register 0
mov cr0, eax
jmp 0x8:0x7e00 ; jump, ie set cs:ip. 8 ptr to code selector in gdt
jmp $
GDTR: ; descriptor to load into lgdt
dw 23 ; gdt table length
dd 0 ; to store physical address for GDT:
GDT:
gdt0 dq 0x0000000000000000 ; null
gdt1 dq 0x00cf9a000000ffff ; code proper order
gdt2 dq 0x00cf92000000ffff ; data
endGDT:
variable dd 0
%include "functions.asm"
times 510-($-$$) db 0
dw 0xaa55
; 0x7e00
protected_mode:
bits 32
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov esp, 0x90000
mov byte [0xb8002], 'P'
mov byte [0xb8003], 24
jmp $
Octocontrabass
Member
Posts: 5586 Joined: Mon Mar 25, 2013 7:01 pm
Post
by Octocontrabass » Sun Nov 18, 2018 11:52 am
The BIOS (or MBR) only loads 512 bytes of your code. Where do you load the rest of your code? Why is your code bigger than 512 bytes?
Why are you setting the segment registers to 0x7c0 instead of setting them to 0 and using "org 0x7c00"?
drnono
Posts: 23 Joined: Sun Aug 09, 2015 11:54 am
Post
by drnono » Sun Nov 18, 2018 1:04 pm
That sorted it thanks. I was trying to call code past the 512 bytes, although it works I have to admit I can't really understand what org does
Octocontrabass
Member
Posts: 5586 Joined: Mon Mar 25, 2013 7:01 pm
Post
by Octocontrabass » Sun Nov 18, 2018 1:19 pm
drnono wrote: I can't really understand what org does
It tells the assembler the offset where your code will be located (relative to the segment base), so you can do things like this:
If you set the segment base to 0, the offset is the same as the linear address, so you can also do things like this: