Placement of %include in my NASM bootloader affects program behavior

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
kushalv238
Posts: 3
Joined: Thu Apr 10, 2025 6:03 am

Placement of %include in my NASM bootloader affects program behavior

Post by kushalv238 »

I am learning to write a 16-bit bootloader using NASM with BIOS interrupts to print strings to the screen. I’ve created a simple print subroutine in an external file (printer.asm), and I'm using %include to bring it into my main bootloader file.

Here’s where it gets weird: depending on where I place the %include directive, I get completely different outputs.

Here's the code and all the placements of the include with the different o/p it gives:

Code: Select all

org 0x7C00
bits 16

%include "printer.asm" ; placing include here prints "S" (probably garbage)

mov bx, GREETING
call print

%include "printer.asm" ; placing include here prints the GREETING message twice (Hello WorldHello World)

loop:
    jmp loop

%include "printer.asm" ; placing include here prints the GREETING message as expected (Hello World)

GREETING:
    db "Hello World", 0

times 510-($-$$) db 0
dw 0xaa55

I understand that NASM is a flat binary format and memory layout matters, but I thought %include is just a textual paste. Why is it behaving this way?

Is the string or code overlapping? Is NASM putting instructions and data in conflicting places? What’s the correct way to organise includes and data to prevent this?

This is the printer.asm file (included file):

Code: Select all

; prints contents stored at BX

print:
    pusha
    mov ah, 0x0e ; tty mode

start:
    mov al, [bx]

    cmp al, 0
    je done

    int 0x10
    
    add bx, 1

    jmp start

done:
    popa
    ret
Thank you in advance!
User avatar
iansjack
Member
Member
Posts: 4789
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Placement of %include in my NASM bootloader affects program behavior

Post by iansjack »

The good news is that you are correct - %include pastes the file at the location of the directive.

Think about what this means. Your program is a flat binary, with no entry point defined. It starts execution at the top of the file. So, in the three cases, what is the first program instruction? And the result of this is …?

It can be instructive to write the programs out in full, inserting the instructions in the include file, and manually step through them without assembling and running on a computer.
sebihepp
Member
Member
Posts: 232
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Re: Placement of %include in my NASM bootloader affects program behavior

Post by sebihepp »

Yes, %include in NASM is just a textual copy&paste.
BIOS jumps directly to either 0x07C0:0x0000 or 0x0000:0x7C00. Or any other combination which results in physical address 0x7C00.
Remember, BIOS didn't set up anything for you. You need to do all this by yourself. Even registers cs and ip can't be relied on.

Go through your code step by step and write what you think happens here in this thread. Then we can tell you where your error is. :-)
Post Reply