Search code examples
assemblynasmx86-16bootloadersubroutine

Where to put assembly subroutines in boot sector file


I have the following boot sector written in nasm:

[org 0x7c00]

my_print_function:
    mov ah, 0x0e
    int 0x10
    ret

_start:
    mov al, 'A'
    call my_print_function
    call my_print_function

_boot:
    jmp $
    times 510-($-$$) db 0
    dw 0xaa55

I compile with nasm -f bin boot.asm -o boot.bin and then run qemu boot.bin, and I only see one character being printed, and it's the garbage character 'U', not 'A'. If I change the order of my_print_function and _start, it works as intended, but the subroutine also runs one time on its own without me calling it, so it prints 'A' three times.

Normally If i was writing assembly, I would just define the my_print_function before my section .text, and put a global _start in my section .text, but it doesn't seem like that does anything here. How can I define and use a subroutine like this without it being ran an extra time just because I define it?


Solution

  • I figured it out when I was trying to do something else and I realised what I was doing wrong. The subroutine needs to come after the infinite jump, so for example:

    [org 0x7c00]
    
    mov al, 'A'
    call my_print_function
    mov al, 'B'
    call my_print_function
    
    jmp $
    my_print_function:
        mov ah, 0x0e
        int 0x10
        ret
    
    times 510-($-$$) db 0
    dw 0xaa55