joshuawoodz
Programmer
Posted is my bootloader code. Everything works until I try to jump to my loaded sector at ES:BX.
Please tell me what I am doing wrong. Probably a very rookie mistake.
Thanks!
Here is my code (not optimized, messy, sorry):
bits 16]
[org 0x7c00]
cli
mov ax, 0x8000 ; Set stack address
mov ss, ax
mov sp, 0
sti
mov [BOOT_DRIVE], dl ; Save boot drive
mov si, TRY_LOAD
call print
mov bx, 0
mov es, bx
mov bx, 1000h
mov al, 1 ; Load 1 sector to ES:BX 0:1000
mov dl, [BOOT_DRIVE] ; from boot disk
call read_disk
jmp [es:bx]
print:
pusha
nextchar:
mov al, [si]
inc si
or al, al
jz exitfunc
call printchar
jmp nextchar
exitfunc:
popa
ret
printchar:
mov ah, 0eh
mov bh, 0
mov bl, 1
int 10h
ret
read_disk:
mov si, RESET_DISK
call print
push ax
push bx
push dx
mov ax, 0
mov dl, [BOOT_DRIVE]
int 0x13 ; Reset the disk
pop dx
pop bx
pop ax
jc err
jmp retry
err:
call printhex
jmp read_disk
mov si, ENDL
call print
retry:
mov ah, 2 ; BIOS read sector function
mov ch, 0 ; Select cylinder 0
mov dh, 0 ; Select head 0
mov cl, 2 ; Start reading from sector 2
int 0x13
jc retry ; error if (CF=1) retry
mov si, LOADED
call print
ret
disk_error:
push ax
mov si, READ_ERROR
call print
pop ax
call printhex
mov si, ENDL
call print
jmp $
printhex: ; ax should have value to print
push bx ; save registers we will use
push cx
push dx
mov dx, 0 ; set the loop counter to 0
mov cx, ax ; copy ax
myloop: ; start loop
cmp dx, 4 ; if run 4 times
je done ; we are done
cmp dx, 3 ; if run 3 times
je four ; print 4th char
cmp dx, 2 ; if run 2 times
je three ; print 3rd char
cmp dx, 1 ; if run once
je two ; print 2nd char
shr ax, 12 ; isolate upper most nibble
compare:
cmp ax, 9 ; if nibble > 9
jg greater ; do greater
add ax, 30h ; if < 9 add 30h to get ASCII char
next:
call printchar ; print the hex char
add dx, 1 ; increase loop counter
mov ax, cx ; recopy value to ax
jmp myloop ; next loop
greater:
add ax, 37h ; if nibble > 9 (A-F) make first ASCII 37h
jmp next
two:
shr ax, 8 ; mov al, ah
and al, 0fh ; isolate ah's lower nibble
jmp compare
three:
mov ah, 0 ; clear ah
shr al, 4 ; isolate al's upper nibble
jmp compare
four:
mov ah, 0 ; clear ah
and al, 0fh ; isolate al's lower nibble
jmp compare
done:
mov si, HEXPREFIX ; print out h at end
call print
pop dx ; restore registers
pop cx
pop bx
ret
; Data
HEXPREFIX db "h ", 0
ENDL db 0ah, 0dh, 0
TRY_LOAD db "Loading sector 2...", 0ah, 0dh, 0
RESET_DISK db "Reset the disk...", 0ah, 0dh, 0
TRY_AGAIN db "Retrying...", 0ah, 0dh, 0
LOADED db "Sector 2 loaded into ES:BX", 0ah, 0dh, 0
BOOT_DRIVE db 0
READ_ERROR db "Fatal Error: Disk read error ", 0
times 510-($-$$) db 0
dw 0xAA55
Please tell me what I am doing wrong. Probably a very rookie mistake.
Thanks!
Here is my code (not optimized, messy, sorry):
bits 16]
[org 0x7c00]
cli
mov ax, 0x8000 ; Set stack address
mov ss, ax
mov sp, 0
sti
mov [BOOT_DRIVE], dl ; Save boot drive
mov si, TRY_LOAD
call print
mov bx, 0
mov es, bx
mov bx, 1000h
mov al, 1 ; Load 1 sector to ES:BX 0:1000
mov dl, [BOOT_DRIVE] ; from boot disk
call read_disk
jmp [es:bx]
print:
pusha
nextchar:
mov al, [si]
inc si
or al, al
jz exitfunc
call printchar
jmp nextchar
exitfunc:
popa
ret
printchar:
mov ah, 0eh
mov bh, 0
mov bl, 1
int 10h
ret
read_disk:
mov si, RESET_DISK
call print
push ax
push bx
push dx
mov ax, 0
mov dl, [BOOT_DRIVE]
int 0x13 ; Reset the disk
pop dx
pop bx
pop ax
jc err
jmp retry
err:
call printhex
jmp read_disk
mov si, ENDL
call print
retry:
mov ah, 2 ; BIOS read sector function
mov ch, 0 ; Select cylinder 0
mov dh, 0 ; Select head 0
mov cl, 2 ; Start reading from sector 2
int 0x13
jc retry ; error if (CF=1) retry
mov si, LOADED
call print
ret
disk_error:
push ax
mov si, READ_ERROR
call print
pop ax
call printhex
mov si, ENDL
call print
jmp $
printhex: ; ax should have value to print
push bx ; save registers we will use
push cx
push dx
mov dx, 0 ; set the loop counter to 0
mov cx, ax ; copy ax
myloop: ; start loop
cmp dx, 4 ; if run 4 times
je done ; we are done
cmp dx, 3 ; if run 3 times
je four ; print 4th char
cmp dx, 2 ; if run 2 times
je three ; print 3rd char
cmp dx, 1 ; if run once
je two ; print 2nd char
shr ax, 12 ; isolate upper most nibble
compare:
cmp ax, 9 ; if nibble > 9
jg greater ; do greater
add ax, 30h ; if < 9 add 30h to get ASCII char
next:
call printchar ; print the hex char
add dx, 1 ; increase loop counter
mov ax, cx ; recopy value to ax
jmp myloop ; next loop
greater:
add ax, 37h ; if nibble > 9 (A-F) make first ASCII 37h
jmp next
two:
shr ax, 8 ; mov al, ah
and al, 0fh ; isolate ah's lower nibble
jmp compare
three:
mov ah, 0 ; clear ah
shr al, 4 ; isolate al's upper nibble
jmp compare
four:
mov ah, 0 ; clear ah
and al, 0fh ; isolate al's lower nibble
jmp compare
done:
mov si, HEXPREFIX ; print out h at end
call print
pop dx ; restore registers
pop cx
pop bx
ret
; Data
HEXPREFIX db "h ", 0
ENDL db 0ah, 0dh, 0
TRY_LOAD db "Loading sector 2...", 0ah, 0dh, 0
RESET_DISK db "Reset the disk...", 0ah, 0dh, 0
TRY_AGAIN db "Retrying...", 0ah, 0dh, 0
LOADED db "Sector 2 loaded into ES:BX", 0ah, 0dh, 0
BOOT_DRIVE db 0
READ_ERROR db "Fatal Error: Disk read error ", 0
times 510-($-$$) db 0
dw 0xAA55