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.
org 0x1000
start:
cli;
lgdt [toc]
sti;
cli;
mov eax, cr0
or eax, 1
mov cr0, eax
;AFTER THIS POINT NOTHING WORKS
jmp 0x8:pmode
BITS 32
pmode:
mov edi, 0xB8000
mov byte [edi], 0x43
mov byte [edi+1], 0x07
hlt;
; GDT CODE
gdt_start:
dd 0
dd 0
dw 0FFFFh
dw 0
db 0
db 10011010b
db 11001111b
db 0
dw 0FFFFh
dw 0
db 0
db 10010010b
db 11001111b
db 0
end_of_gdt:
toc:
dw end_of_gdt - gdt_data - 1
dd gdt_data
Code stops working after moving eax back to cr0. It works perfectly to the jump. Since it, jumps don't work correctly, so I think there's something wrong with it. Does anybody know what? Code is loaded to 0x1000 in real mode by bootloader. Then, execution jumps to the "start" label of this code. Bootloader and stage2 are in separated files.
If anybody knows where can the problem be, please help.
Last edited by HugeCode on Tue Apr 16, 2013 9:52 am, edited 3 times in total.
Why would specifically the jump be wrong if you only demonstrated the code as a whole to be failing?
Hint: DS must change between its first and second usage. The second use is guaranteed to have the wrong value, and so might the first depending on your bootloader.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
As Combuster asks, why do you say the fault is the jump? Are you running it under a debugger and have found the processor faults there? If not, what makes you suppose that the faulting instruction is not when you try to write to the screen (which is obviously going to fault if ds doesn't contain a valid selector) or any other instruction? How do you know it is even getting as far as the moves from and to the control register?
You haven't given us enough information, and you would appear to be making unwarranted assumptions. (On the other hand, it's possible that you are running under a debugger so know where the code is faulting. If that is the case, just look at the registers and it should be obvious what the fault is.)
Either I'm being stupid, or your CS is wrong. As far as I can see you have not defined a descriptor for that value. But, you are jumping to 0x08:xxxx, and your CS is 0x1000; your code has never tried to execute the jump. Something is wrong earlier, probably an invalid GDT.
Code is loaded to 0x1000 in real mode by bootloader.
Breakpoint 13, 0x00010019
That just proved your original statement was false.
In other words, the first bug is the org statement, and from CS != 0, may more bugs will follow.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Yes, that's true. It's loaded to es=0x1000, so it means it's loaded to 0x10000. I have "repaired" my origin to 0x10000. What's wrong next? What do I need to do?
I'd suggest that you single-step the code under a debugger, inspect your GDT, and see exactly where the fault is happening. It really ought to be fairly obvious.
Repaired, still same behaivor. But i've done single steps and I found out that my code jumps to 0x1e = code descriptor start(0) + 1e instruction start. How can I jump correctyl to my label? When I set origin to 0x1000 before label and I try to jump there by
I'm using NASM for compilation, GDB for debugging (with intel syntax set for disasm). On the beginning of stage2 (code I've posted here), it's 0x1000 (value got by gdb info registers).