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.
retwas going somewhere you didn't want, giving a big hint in the right direction. - Peter Cordes