Drawing inspiration from cfenollosa, I was writing my boot sector in ASM. Having just learnt how to use includes in ASM, I was writing code to print a given string using a loop.

My boot sector consisted of two files:

boot_print.asm

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
; Boot sector offset
[org 0x7c00]

mov bx, HELLO
call print

call print_nl

; Infinite loop, this hangs the OS
jmp $

; Include the print code
%include "boot_print.asm"

HELLO:
	db 'HI', 0

; Junk padding
times 510 - ($ - $$) db 0
; Bytes 511 and 512 hold data to indicate if bootable
dw 0xaa55

This is the main file which instantiates the boot sector and prints the string HELLO.

Now we can compile the code and run it using qemu as shown:

nasm -f bin boot_main.asm -o boot.bin; and qemu-system-x86_64 boot.bin

Which gives the much expected result:

NASM Success Hi

But what if we mess around with the code a little bit? coming from C, I’m used to having my includes at the beginning. So similarly I tried moving the includes to the beginning:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
 [org 0x7c00]

+%include "boot_print.asm"
+
 mov bx, HELLO
 call print

@@ -7,8 +9,6 @@ call print_nl

 jmp $

-%include "boot_print.asm"
-
 HELLO:
        db 'HI', 0

But running this, we are greeted with gibberish:

NASM Failure Hi

Interesting. But why is this happening? Lets look at the hexdump to see if we can find any difference

Hexdump of modified main.asm

1
2
3
4
5
6
7
0000000 8a60 3c07 7400 b409 cd0e 8310 01c3 f1eb
0000010 c361 0eb4 0ab0 10cd 0db0 10cd f2eb 29bb
0000020 e87c ffdc ebe8 ebff 48fe 0049 0000 0000
0000030 0000 0000 0000 0000 0000 0000 0000 0000
*
00001f0 0000 0000 0000 0000 0000 0000 0000 aa55
0000200

Hexdump of original main.asm

1
2
3
4
5
6
7
0000000 29bb e87c 0005 14e8 eb00 60fe 078a 003c
0000010 0974 0eb4 10cd c383 eb01 61f1 b4c3 b00e
0000020 cd0a b010 cd0d eb10 48f2 0049 0000 0000
0000030 0000 0000 0000 0000 0000 0000 0000 0000
*
00001f0 0000 0000 0000 0000 0000 0000 0000 aa55
0000200

Why? The answer is simple. If we include the boot_print.asm file in the starting, NASM will execute that before the other code, this would mean it will print random gibberish onto the screen, as per whatever is the value stored in the location stored in the bx register.

Labels in NASM are executed sequentially even if not called.