How to use the directives ORG and SECTION with NASM
In this post, I write about my first baby steps with NASM, which is a complex tool that can output many different formats. Depending on the output format, the syntax of NASM changes a little bit. For instance, the directive ORG is legal only in combination with the option -f bin which instructs NASM to produce a pure binary file in output. Additionally, I discovered how the directive SECTION assumes a slightly different meaning depending on the used option for output: either -f bin or -f obj (which produces a 16-bit Object Module file as the option /omf of MASM). I understood how I could take advantage of the flat binary output format of NASM to produce my SOFTWARE.BIG1 without the need of any linker. I summarize here my experience in three main steps:
- How to use the directives ORG and SECTION with NASM
- How to create a boot sector program with NASM
- How to make a SOFTWARE.BIG with NASM
How to use the directives ORG and SECTION with NASM
MASM and NASM both have a directive ORG but
the effects in the creation of the assembled output are different. I am not
going to present the differences among MASM and NASM about the
ORG
directive, but just write about what the
ORG directive is and how to use it in the
contest of NASM. 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 unless one redefines the
section with a vstart= option (ahead in this post, I clarify aspects of this sentence with examples, so try to remember it).
There are three important features to remember about ORG:
- 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.
The function of the directive SECTION is to define and organize blocks or sections of the binary output file. The NASM's authors write that the directive SECTION is synonymous for the MASM directive SEGMENT2, but this is not what it seems to me when I use it. I can use the directive SECTION to define segments (as I am going to demonstrate in the post "How to make a SOFTWARE.BIG") but this is just one of the different possible way of using it. Moreover the syntax and the usage of the directive SECTION in NASM changes depending on the used option for output: either -f bin or -f obj:
- -f bin: SECTION can have additional parameters such as align=, start= and vstart=
- -f obj: SECTION can have other additional parameters such as PRIVATE, PUBLIC, COMMON, STACK, align, use16, use32 etc.
In case of -f obj, the directive SECTION and SEGMENT appears to me to be like synonymous and they both behave in the same way in NASM (probably this is the aspect that the authors of NASM refer to when they write that SECTION and SEGMENT are synonymous).
At this point, I want to show my experience made with the directives ORG and SECTION.
I created an initial file "Learn NASM - 00.asm", then I assembled it with NASM using the command: nasm -f bin "Learn NASM - 00.asm" -l "Learn NASM - 00.lst". I did changes and looked at the effects in the list file "Learn NASM - 00.lst" and in the binary one "Learn NASM - 00"3. In the version that I present here, you can see the ORG directive at line 11. At line 27, I placed 3 bytes 0x11, 0x22 and 0x33 just to have a visual reference. As you can tell by looking at the left side of the same line, NASM starts assembling them at address 0x00. At lines 41 and 42, I defined two section with arbitrary names: "red" and "blue". I said that the section red started at 0x7C10 and the section blue started at 0x7C50. Additionally, I set the virtual start of addresses at 0x0300 for the blue section (vstart=0x03004). I mentioned already that the vstart= option resets the address counter that was set with the ORG directive and I am about to show it now.
Continuing in the program, I wrote the MsgOne and I referenced it at line 47 with the MNEMONIC mov ax, MsgOne. I would like you to observe the OPCODE at line 47 (0xB80000) which has an offset of 0x00 from the beginning of the section red. In fact, at the first glance that NASM gave to the program, it saw the message MsgOne that started immediately at the beginning of the section red. You can observe the same story at line 54, with the MsgTwo of section blue. Finally, I switched back again to the section red and I placed MsgTree which was referenced at address 0x07 from the start of the red section. NASM let the programmer switch from section to section in a very easy way, as you can tell by the way I wrote the program from line 45 onwards. I use to declare the section all at the beginning (like lines 41 and 42) because this (almost) fixes already the order by which the sections appears in the binary file. More precisely: NASM organizes the different sections in the binary file depending on the value passed to the option start= or by the chronologic order by which the section declaration appears in the source file if the start= option were not specified.
Fig. A - The binary file "Learn NASM - 00" |
In Fig. A, you see the binary file which started at address 0x00, but it is supposed to appear in memory at address 0x7C00. At least this is what I said to NASM when I wrote the directive ORG 0x7C00. At the address 0x10 of the binary file (which corresponds to 0x7c00 + 0x10 in the calculation that NASM did considering the ORG directive) you see the section red. Similarly, at address 0x50 of the binary file (0x7c00 + 0x50) you see the section blue. If you try to put what you see here together with the lines 41 and 42 of the list file and the options start=0x7C10 and start=0x7C50, you should be able to make sense of it. In my intention, this should explain the sentence wrote previously: "Its sole function (the ORG directive) is to specify one offset which is added to all internal address references [...]".
Now, I want you to observe the OPCODES of the two move instructions (0xB8107C and 0xB8177C) and compare them with the OPCODES in the list file at lines 48 and 60. As you can see, the addresses in the binary files are equal to the addresses calculated in the list file plus the start of the section. But what happened with the OPCODE 0xB80003 (marked in blu in Fig. A at address 0x55 in the binary file)? The MsgTwo started at a relative offset of 0x00 Bytes from the begin of the blue section (see the OPCODE in the list file at line 54) but I declared a virtual start for the addresses of the blue section at 0x0300 when I used the option vstart=0x0300 at line 42. In my intention, this should explain the effect of the option vstart= and explain the sentence wrote previously: "[...] unless one redefine the section with a vstart= option [...]".
Finally, I want you to observe that, regardless the way I switched among sections in the program (lines 41, 42, 45, 51 and 57 of the list file), NASM groups the Bytes belonging to a section altogether and places the sections in the order specified by the start= option. If no start= option is available, then NASM places the section immediately following the end of the previous one, with as many Bytes of alignment, from the end of the previous section, as specified in the option align= (if the align= option is not available, NASM aligns at boundary of paragraph).
This concludes, for the moment, the initial understanding of the directives ORG and SECTION, but I am going to continue on the same topic in the next upcoming posts.
Comments
Post a Comment