I have a code:
[org 0x7c00]
CODE_SEG equ GDT_code - GDT_start
DATA_SEG equ GDT_data - GDT_start
cli
lgdt [GDT_descriptor]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp CODE_SEG:start_protected_mode
jmp $
GDT_start:
GDT_null:
dd 0x0
dd 0x0
GDT_code:
dw 0xffff
dw 0x0
db 0x0
db 0b10011010
db 0b11001111
db 0x0
GDT_data:
dw 0xffff
dw 0x0
db 0x0
db 0b10010010
db 0b11001111
db 0x0
GDT_end:
GDT_descriptor:
dw GDT_end - GDT_start - 1
dd GDT_start
[bits 32]
start_protected_mode:
mov ax, DATA_SEG
mov ds, ax
mov es, ax
mov al, "A"
mov ah, 0x0f
mov [0xb8000], ax
jmp $
times 510-($-$$) db 0
dw 0xaa55
It works fine on qemu, but when I try to boot it on the real pc, it just reboots. I found in the Internet, that my problem is Segment Registers. How can I set them up, so the program could start working on real PC?
I've tried to set DS and ES to 0x07C0, but then program stopped working on qemu too.
First off, you have to set
dsregister tozerosince you are set the origin address toorg 0x7c00. This had been done byqemuand most probably with other virtual machines for you. But now during migrating to physical machine, you must take care of it yourself:Then, do not forget to set the
stackwith something like this or another area as you'd like: