This can be particularly useful for modularizing code, reusing macros and constants, and improving code organization. This article provides an in-depth look at the %INCLUDE
directive, including its usage, variations, and best practices for managing include guards.
Understanding the %INCLUDE
Directive
The %INCLUDE
directive tells the NASM assembler to read and process another file as if its content were directly included in the current source file. This directive is particularly useful for breaking down large assembly programs into manageable modules or including commonly used macros and constants.
Basic Usage of %INCLUDE
The syntax for the %INCLUDE
directive is straightforward:
%include 'filename.inc'
Here, filename.inc
is the path to the file you want to include. The file extension .inc
is a convention, but you can use any extension.
Example: Including a File
Suppose you have a file macros.inc
that contains macro definitions:
; macros.inc
%macro PRINT_STRING 2
mov eax, 4 ; syscall number for sys_write
mov ebx, %1 ; file descriptor
mov ecx, %2 ; address of string
mov edx, %2_len ; length of string
int 0x80 ; call kernel
%endmacro
You can include and use these macros in your main assembly file main.asm
:
; main.asm
%include 'macros.inc' ; Include macro definitions
section .data
hello db 'Hello, World!', 0xA
hello_len equ $ - hello
section .text
global _start
_start:
PRINT_STRING 1, hello ; Use the PRINT_STRING macro to print the string
; Exit program
mov eax, 1 ; syscall number for sys_exit
xor ebx, ebx ; exit code 0
int 0x80 ; call kernel
Variations and Path Handling
NASM allows flexible handling of paths in %INCLUDE
. You can specify relative or absolute paths, and the NASM assembler will search for the file accordingly. It's common to organize include files in a dedicated directory:
%include 'includes/macros.inc'
During Assembling, we can pass the include file path to the NASM
:
NASM_INCLUDE_PATH := /path/to/includes
main.o: main.asm
nasm -f elf32 -o $@ -I$(NASM_INCLUDE_PATH) $<
In this Makefile snippet, -I
flag is used to specify the include path directly to NASM.
Include Guards
Include guards are essential for preventing multiple inclusions of the same file, which can lead to redefinition errors and other issues. In NASM, include guards can be implemented using conditional assembly directives.
Example of Include Guards
Here’s how you can implement include guards in NASM:
; macros.inc
%ifndef MACROS_INC
%define MACROS_INC
%macro PRINT_STRING 2
mov eax, 4 ; syscall number for sys_write
mov ebx, %1 ; file descriptor
mov ecx, %2 ; address of string
mov edx, %2_len ; length of string
int 0x80 ; call kernel
%endmacro
%endif ; MACROS_INC
The macros.inc
file is wrapped with a %ifndef
(if not defined) and %define
pair, ensuring that its content is included only once. If MACROS_INC
is already defined, the content between %ifndef
and %endif
will be ignored.
Advanced Usage
Including Assembly Code Conditionally
You can use conditional assembly directives with %INCLUDE
to include files based on certain conditions:
%ifdef USE_MACROS
%include 'macros.inc'
%endif
In this example, macros.inc
is included only if USE_MACROS
is defined.
Nested Includes
NASM supports nested includes, where an included file can itself include other files. Care must be taken to avoid circular dependencies:
; main.asm
%include 'macros.inc'
%include 'config.inc'
section .data
hello db 'Hello, World!', 0xA
hello_len equ $ - hello
section .text
global _start
_start:
PRINT_STRING 1, hello ; Use the PRINT_STRING macro to print the string
; Use configuration settings
mov eax, CONFIG_VALUE
; Exit program
mov eax, 1 ; syscall number for sys_exit
xor ebx, ebx ; exit code 0
int 0x80 ; call kernel
Best Practices
- Use Include Guards: Always use include guards to prevent multiple inclusions.
- Organize Include Files: Keep your include files in a dedicated directory to improve organization and readability.
- Use Relative Paths: Prefer relative paths for portability and ease of use across different development environments.
- Document Include Files: Provide comments and documentation in your include files to clarify their purpose and usage.