How to create a boot sector program with NASM

Reference picture of the post "How to create a boot sector program with NASM"

In this post, I continue the summary of the experience made while learning the directives SECTION and ORG of NASM. In my previous post ("How to use the directives ORG and SECTION with NASM") I wrote that the directive SECTION can be used to define more than just segments. The NASM's authors write that the directive SECTION is synonymous for the MASM directive SEGMENT1, but SECTION in NASM is broader than SEGMENT in MASM especially in combination with the option -f bin.
To demonstrate what I mean, I created a boot sector program in NASM and I used the directive SECTION. In the NASM documentation at Chapter 13.1.3 "ORG Doesn't Work", the authors write about the difference between MASM and NASM in the use of the directive ORG. To explain what the NASM authors mean by that, they provide a short example of a boot sector program and they suggest the use of the TIME directive: TIMES 510-($-$$) DB 0

I think that there is a better way of creating a boot sector program which is leveraging the capabilities of the directive SECTION.

The file: "Learn NASM - 01.asm"
;############################################################################## ; Learn NASM - 01.asm ; ; ; Build with: ; nasm -f bin "Learn NASM - 01.asm" -l "Learn NASM - 01.lst" -o "boot_01.bin" ;############################################################################## ;############################################################################## ; Full definition of section IN COMBINATION WITH -f bin !!! ; ; Sections can be aligned at a specified boundary following the previous ; section with align=, or at an arbitrary byte-granular position with start=. ; ; align= -> can be any power of 2. ; start= -> is a flat address (example: 0x01_7C00) where the section starts ; in memory. ; vstart= -> the virtual start address, which will be used for the calculation ; of all memory references within that section. ;############################################################################## section BootSignature start=0x7dfe section BIOSParameterBlock start=0x7c00 section BootCode align=1 ; The section starts with no bytes of ; gap from the end of the previous ; section. section BootSignature db 0x55, 0xaa section BIOSParameterBlock ;-------------------------------------------------------------------------- ; IMPORTANT!!! ; The first 3 bytes of code are considered as integral part of the BPB! ;-------------------------------------------------------------------------- ; EB 3c: Jump over the BIOS Parameter Block ; 90: NOP this is one byte for allignment within the BPB ; db 0xeb, 0x3c, 0x90 ;-------------------------------------------------------------------------- ; Dummy definition of BPB for demonstrative purpose only ;-------------------------------------------------------------------------- db 'This is a dummy BIOS Parameter Block of a FAT16 partition..' section BootCode ;-------------------------------------------------------------------------- ; Dummy definition of code... ;-------------------------------------------------------------------------- xor ax, ax

As you can see in "Learn NASM - 01.asm", I defined three sections: BootSignature, BIOSParameterBlock and BootCode. Regardless of the chronological sequence that I used to define them, NASM placed the same in the binary output file according to what is specified in the option start=. I decided on purpose to define the section BootSignature as first because I wanted to show you that NASM looks at the option start= to organize the different sections and only if the option start= were not available, NASM considers the chronological sequence of the declaration of sections. I showed this last aspect with the declaration of the section BootCode where I didn't use the option start= but the option align=12 Immediately after the declaration of the sections, I started to fill them with values. I did immediately the BootSignature section so that it was done and checked out in my mind. Following, I filled a dummy BIOSParameterBlock and a dummy BootCode section. Fig. A shows the results of it.

Fig. A - The binary file "boot_01.bin"
Fig. A - The binary file "boot_01.bin"

As you can see, the 512 Bytes are exactly as I wanted them to be and the "boot_01.bin" file contains 0x7C00 bytes before it all with a value of 0x00. This is correct since I didn't use any ORG directive in "Learn NASM - 01.asm". In this way, I wanted to show you also the normal effect when the directive ORG is not used.

In my previous post ("How to use the directives ORG and SECTION with NASM") I wrote that the directive ORG can be placed anywhere in the source code but only once so I placed it at the end of the source file and you can see the effects in Fig. B.

The file: "Learn NASM - 02.asm"
;############################################################################## ; Learn NASM - 02.asm ; ; ; Build with: ; nasm -f bin "Learn NASM - 02.asm" -l "Learn NASM - 02.lst" -o "boot_02.bin" ;############################################################################## ;############################################################################## ; Full definition of section IN COMBINATION WITH -f bin !!! ; ; Sections can be aligned at a specified boundary following the previous ; section with align=, or at an arbitrary byte-granular position with start=. ; ; align= -> can be any power of 2. ; start= -> is a flat address (example: 0x01_7C00) where the section starts ; in memory. ; vstart= -> the virtual start address, which will be used for the calculation ; of all memory references within that section ;############################################################################## section BootSignature start=0x7dfe section BIOSParameterBlock start=0x7c00 section BootCode align=1 ; The section starts with no bytes of ; gap from the end of the previous ; section. section BootSignature db 0x55, 0xaa section BIOSParameterBlock ;-------------------------------------------------------------------------- ; IMPORTANT!!! ; The first 3 bytes of code are considered as integral part of the BPB! ;-------------------------------------------------------------------------- ; EB 3c: Jump over the BIOS Parameter Block ; 90: NOP this is one byte for allignment within the BPB ; db 0xeb, 0x3c, 0x90 ;-------------------------------------------------------------------------- ; Dummy definition of BPB for demonstrative purpose only ;-------------------------------------------------------------------------- db 'This is a dummy BIOS Parameter Block of a FAT16 partition..' section BootCode ;-------------------------------------------------------------------------- ; Dummy definition of code... ;-------------------------------------------------------------------------- xor ax, ax ;-------------------------------------------------------------------------- ; I put the ORG directive at the end or the program just for demonstrative ; purpose and show that ORG can be placed anywhere in the file but only ; once. ; A better practice is to place the ORG directive immediatelly at the ; beginning of the file. ;-------------------------------------------------------------------------- org 0x7c00 ; The function of the ORG directive is to specify ; the origin address which NASM will assume ; the program begins at when it is loaded ; into memory. Its sole function is to specify one ; offset which is added to all internal address ; references within the section (section) unless ; one redefine the section with a vstart= option. ; ; IMPORTANT!!! ; -> org can be used only one time in the whole ; source code. ; -> org can be placed anywhere in the source code ; (but only once). ; -> org can be used only with -f bin output file ; format (it is not the same as in MASM).


Fig. B - The binary file "boot_02.bin"
Fig. B - The binary file "boot_02.bin"

With this post, I showed you how the directive SECTION can be used to define something more than just segments and I demonstrated that the directive SECTION is not just a synonymous of SEGMENT because SECTION in NASM has a broader scope than SEGMENT in MASM. With this last statement, I am not saying anything about NASM being better than MASM. I am just presenting the differences in the way of usage. Once you know the differences, you can use them at your convenience to reach the purpose you have for your program.

This concludes, for this post, the experiments with the directives SECTION and ORG, but I am still going to continue on the same topic in the next upcoming posts.



  1. See Chapter 7.3 "SECTION or SEGMENT: Changing and Defining Sections" of the NASM documentation. [click back]
  2. The argument to align= can be any power of 2. Observe that 1 is a power of 2 and more precisely it is 2^0. You can also try to delete the option align= or specify a different value to see the effects in the binary output file. [click back]

<PREV.  -  ALL  -  NEXT>

Comments