I'm trying to develop a basic bootloader, but I ran into a problem when I tried to create a function for reading additional sectors from a hard drive. I'm developing it on Kali Linux in NASM and using QEMU as my emulator. This is my main bootloader file:
[org 0x7c00]
mov bp, 0x8000
mov sp, bp
call read_disk
mov si, my_string
call print ;prints a string, si points to the string to be printed
jmp $
read_disk
mov ah, 0x02 ;read from disk
mov al, 0x01 ;read one sector
mov ch, 0x00 ;read from cylinder 0
mov dh, 0x00 ;read from head 0
mov cl, 0x02 ;read the second sector
mov bx, 0
mov es, bx
mov bx, 0x7c00+512
int 0x13
jc disk_error ;BIOS sets the carry flag if disk read was unsuccessful
ret
disk_error:
mov si, error_msg
call print
jmp $
;
;Functions
;
%include "functions/print.asm"
%include "functions/print_hex.asm"
%include "functions/print_nl.asm"
%include "functions/calc_len.asm"
%include "functions/find_string.asm"
;
;Data
;
error_msg:
db 'Error reading disk', 0
times 510-($-$$) db 0 ;pad out the rest of the bootloader with zeros to increase the size to 512 bytes
dw 0xaa55 ;Magic bytes so BIOS recognizes the hard drive as bootable
;
;SECOND SECTOR
;
my_string:
db 'Disk read successful', 0
times 512 db 0 ;need to pad out the rest of the sector with zeros since QEMU requires it
As you can see, my_string lies after 512 bytes, in the second sector of the emulated hard drive. But when I compile and run the bootloader, it doesn't output anything. In the code I provided above, I'm printing my_string after the read_disk function is over. But strangely enough, If I move the two lines that print my_string inside the function, it works.
This is the code that works:
[org 0x7c00]
mov bp, 0x8000
mov sp, bp
call read_disk
jmp $
read_disk
mov ah, 0x02 ;read from disk
mov al, 0x01 ;read one sector
mov ch, 0x00 ;read from cylinder 0
mov dh, 0x00 ;read from head 0
mov cl, 0x02 ;read the second sector
mov bx, 0
mov es, bx
mov bx, 0x7c00+512
int 0x13
jc disk_error ;BIOS sets the carry flag if disk read was unsuccessful
mov si, my_string
call print ;prints a string, si points to the string to be printed
ret
disk_error:
mov si, error_msg
call print
jmp $
;
;Functions
;
%include "functions/print.asm"
%include "functions/print_hex.asm"
%include "functions/print_nl.asm"
%include "functions/calc_len.asm"
%include "functions/find_string.asm"
;
;Data
;
error_msg:
db 'Error reading disk', 0
times 510-($-$$) db 0 ;pad out the rest of the bootloader with zeros to increase the size to 512 bytes
dw 0xaa55 ;Magic bytes so BIOS recognizes the hard drive as bootable
;
;SECOND SECTOR
;
my_string:
db 'Disk read successful', 0
times 512 db 0 ;need to pad out the rest of the sector with zeros since QEMU requires it
I'd be very grateful if someone can explain this strange oddity to me.