Skip to content

Instantly share code, notes, and snippets.

@iximeow
Created December 12, 2017 06:41
Show Gist options
  • Save iximeow/6411432ea181700416d938bcae2eb962 to your computer and use it in GitHub Desktop.
Save iximeow/6411432ea181700416d938bcae2eb962 to your computer and use it in GitHub Desktop.
x86 totally supports read/write to 0
; assemble like `nasm bootloader.asm` (will produce a flat binary output by default)
; run like `qemu-system-x86_64 bootloader`
[BITS 16]
[ORG 7c00h]
init:
mov cx, 0xB800
mov gs, cx
call clr_vga
mov si, HELLO
call write_str
mov si, 0x0000
mov fs, si
push ds
mov ds, si
mov ax, 0x78
mov word [fs:si], ax
call write_str
mov ax, word [fs:si]
pop ds
mov si, REALRW
call write_str
; so we wrote and printed 'x' in real mode.. now to do it in protected mode
; load up gdt and switch to protected mode!
cli
lgdt [gdt_ptr]
mov eax, cr0
or al, 1
mov cr0, eax
; sti ; commented out because i don't feel like listening to interrupts
jmp 0x08:protected_code
protected_code:
; now some 32bit code...
[BITS 32]
mov ecx, 0x10
mov ds, ecx
mov es, ecx
mov fs, ecx
mov gs, ecx
mov ss, ecx
; eax points to cursor loc now...
xor eax, eax
mov byte [eax], 0x79 ; put a Y there
mov al, byte [eax] ; read it back
mov edi, dword [CURSOR_LOC]
add edi, 0xb8000
stosb ; store al to CURSOR_LOC (write 'y')
mov al, 0x07
stosb ; set characteristics
mov ecx, PROTEND - PROTRW
mov esi, PROTRW
protected_mode_write_loop:
movsb ; copy string byte to VGA memory
stosb ; set its characteristics
loop protected_mode_write_loop
spin:
jmp spin
[BITS 16]
write_str:
push ax
push si
xor ax, ax
write_str_each_char:
mov al, byte [si]
cmp al, 0
je write_str_done
inc si
call write_char_default_attr
jmp write_str_each_char
write_str_done:
pop si
pop ax
ret
write_char_default_attr:
push bx
mov bl, 0x07
jmp write_char_inner
write_char:
push bx
write_char_inner:
push di
mov di, [CURSOR_LOC]
mov byte [gs:di], al
inc di
mov byte [gs:di], bl
inc di
mov [CURSOR_LOC], di
pop di
pop bx
ret
clr_vga:
mov di, 4000
clr_vga_loop:
dec di
mov byte [gs:di], 0x00
cmp di, 0
jne clr_vga_loop
mov word [CURSOR_LOC], 0
ret
HELLO:
db ':hello:', 0
REALRW:
db ':if you saw an x, real mode null write is ok:', 0
PROTRW:
db ':if you saw a y, protected mode null write is ok:', 0
PROTEND:
CURSOR_LOC:
dd 0
gdt_ptr:
dw 24 ; 24 byte GDT - two entries, plus null selector, each is 8 bytes, so 3 * 8
dd a_gdt
a_gdt:
dd 0
dd 0
; gdt entries are dumb and wart-y
; code
dw 0xffff
dw 0
db 0
db 10011010b
db 11001111b
db 0
; data
dw 0xffff
dw 0
db 0
db 10010010b
db 11001111b
db 0
; pad for one sector
times 510-($-$$) db 0
db 0x55
db 0xAA
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment