0x7c00
;0xaa55
- the magic number signifying to the BIOS that it's a bootable disk that contains a bootloader;0x7c00
and the bootloader code gets executed;NTLDR
, which eventually loads the Windows kernel image c:\Windows\System32\ntoskrnl.exe
;0xAA55
that indicate, that this sector contains a bootloader and the medium is bootable:times 510 - ($-$) db 0
- instructs NASM to fill the space between instruction jmp loop
(2 bytes in size) and the last two bytes 0xaa55
(line 13, signifies the magic bytes of the boot sector) with 0x00
508 null bytes, to make sure that the boot sector is exactly 512 bytes in size.jmp loop
(2 bytes)times 510 - ($-$) db 0
reads as - pad the binary with 00 bytes 508 times: 510 - (2-0) = 508. bootloader.bin
, we can confirm that our bootloader file structure is as follows - 2 bytes for the jmp loop
instruction (eb fe
) at offset 0, followed by 510 null bytes and 2 magic bytes 0x55aa
at the end, making up a total of 512 bytes:0x7c00
as shown in the below graphic:0x7c00
by performing two simple tests.add bx, 0x7c00
is commented out - we will uncomment it in Test 2 and confirm that the bootloader is indeed loaded at 0x7c00
.X
that is a memory offset to the character B
from the start of computer memory. Important to highlight - label offset is not relative to the start of our code location in memory, but from the start of computer memory.bx
with the offset of the label x
(0 in our case) with the aim to make bx
point to the character B
.bx
(take the value from memory address pointed to by the bx
) and put it in al
al
to the screen, which one could expect to be the character B
, but as we will soon see, will not be the case.x
) as offsets from the start of computer memory and not from the start of the memory location where our code is loaded to.nasm -f bin .\bootloader-x.asm -o bootloader.bin
and launch it with qemu-system-x86_64.exe C:\labs\bootloader\bootloader.bin
and see the result:B
, we actually see a character S
, which suggests that we are simply reading the wrong memory location and our character B
is not stored in memory where we thought it was.bootloader.bin
we've just compiled:42
, which is a letter B
in ASCII - the character our label x
is pointing to, which we wanted to print to the screen with Test 1, but failed. Let's look at the Test 2.B
is located in memory. Let's now take the same code we used in the Test 1 and uncomment the instruction add bx, 0x7c00
in line 12, which adds 0x7c00
to our label x
:nasm -f bin .\bootloader-x.asm -o bootloader.bin
and launch it with qemu-system-x86_64.exe C:\labs\bootloader\bootloader.bin
:B
is finally printed to the screen, which confirms that our bootlaoder code (and the character B
) is located at memory location 0x7c00
.42bb 0000 8a07 b40e cd10 0000
(the starting bytes of our bootloader, as seen in the hex dump on the right hand side highlighted in lime), we can see that our bootloader resides at 44D07C00:B
(in red) is our character B
that we print to the screen, that sits at the start of our bootloader - at offsets 0x0
in a raw binary on the disk and 0x07c00
when it's loaded to memory by the BIOS as a bootloader, or in the case of emulation with qemu - at 0x44d
07c00
.org 0x7c00
/ NASM org directive0x7c00
to our operations each time we need to reference some label is not ideal. Lukcily, we can instruct NASM to calculate offsets to the labels in our code in relation to the memory address of our liking (i.e 0x7c00
), by utilising the directive org 0x7c00
. This simply tells NASM that we expect our program to be loaded at 0x7c00
and it's almost like we're saying to NASM: "Hey, please keep in mind that we expect this code to be located at 0x7c00
, so whenever you calculate any offsets for us, please calculate those in relation to that 0x7c00
- much appreciated".org 0x7c00
before our code - in line 4:B
character is still printed:D:\
in my case) boot sector using dd
utility on Linux or HxD
on Windows: