Assembly Multi-File Projects — Linking Multiple Object Files
In this tutorial, you will learn about Assembly Multi. We cover key concepts, practical examples, and best practices to help you master this topic.
Multi-file assembly projects use global/extern directives to share symbols across files, with separate compilation and linking into a single executable for modular code organization.
What You'll Learn
- global and extern directives
- Separate assembly and linking
- Creating reusable libraries
- Object file formats (ELF)
Why It Matters
Real projects split code into modules for maintainability and reuse. DodaZIP organizes its assembly-optimized routines across multiple files by compression algorithm.
Real-World Use
Large assembly projects like operating systems, embedded firmware, game engines, and crypto libraries split code into logical modules linked together.
flowchart LR
A["file1.asm"] --> B["NASM"]
A --> C["file1.o"]
D["file2.asm"] --> E["file2.o"]
B --> F["Linker (ld)"]
E --> F
F --> G["executable"]
style A fill:#2563eb,stroke:#2563eb,color:#fff
style D fill:#dbeafe,stroke:#2563eb,color:#1e40af
style B fill:#dbeafe,stroke:#2563eb,color:#1e40af
style E fill:#dbeafe,stroke:#2563eb,color:#1e40af
style F fill:#dbeafe,stroke:#2563eb,color:#1e40af
style G fill:#f1f5f9,stroke:#94a3b8,color:#64748b
Exporting Symbols (global)
; math.asm
section .text
global add_numbers
global multiply_numbers
add_numbers:
mov rax, rdi
add rax, rsi
ret
multiply_numbers:
mov rax, rdi
imul rax, rsi
ret
Importing Symbols (extern)
; main.asm
extern add_numbers
extern multiply_numbers
section .data
msg db "Result: %d", 10, 0
section .text
global _start
_start:
mov rdi, 10
mov rsi, 20
call add_numbers
; rax = 30
mov rdi, 5
mov rsi, 6
call multiply_numbers
; rax = 30
mov rax, 60
xor rdi, rdi
syscall
Compilation and Linking
# Assemble each file separately
nasm -f elf64 math.asm -o math.o
nasm -f elf64 main.asm -o main.o
# Link together
ld math.o main.o -o program
# Run
./program
Modular Library Example
; io.asm — I/O routines
section .data
section .text
global print_string
global read_string
print_string:
; rsi = string, rdx = length
mov rax, 1
mov rdi, 1
syscall
ret
read_string:
; rsi = buffer, rdx = max_length
mov rax, 0
mov rdi, 0
syscall
ret
; calc.asm — math routines
section .text
global square
global sum_array
square:
mov rax, rdi
imul rax, rax
ret
sum_array:
; rsi = array pointer, rdx = count
xor rax, rax
xor rcx, rcx
.loop:
add rax, [rsi + rcx * 8]
inc rcx
cmp rcx, rdx
jl .loop
ret
; main.asm
extern print_string, square, sum_array
section .data
array dq 1, 2, 3, 4, 5
len equ 5
section .text
global _start
_start:
mov rdi, 7
call square
; rax = 49
mov rsi, array
mov rdx, len
call sum_array
; rax = 15
mov rax, 60
xor rdi, rdi
syscall
Sharing Data Across Files
; data.asm
section .data
global shared_value
global buffer
shared_value dq 42
buffer times 256 db 0
; worker.asm
extern shared_value, buffer
section .text
global process_data
process_data:
mov rax, [shared_value]
add rax, rdi
mov [shared_value], rax
ret
Include Files
; macros.asm — included in other files
%macro print 2
mov rax, 1
mov rdi, 1
mov rsi, %1
mov rdx, %2
syscall
%endmacro
%macro exit 1
mov rax, 60
mov rdi, %1
syscall
%endmacro
; main.asm
%include "macros.asm"
section .data
msg db "Hello", 10
len equ $ - msg
section .text
global _start
_start:
print msg, len
exit 0
Makefile for Multi-File Projects
ASM = nasm
ASMFLAGS = -f elf64
LINKER = ld
TARGET = program
OBJS = main.o math.o io.o
$(TARGET): $(OBJS)
$(LINKER) $(OBJS) -o $(TARGET)
%.o: %.asm
$(ASM) $(ASMFLAGS) $< -o $@
clean:
rm -f $(OBJS) $(TARGET)
Common Mistakes
1. Missing global directive
Symbols are local by default. Without global, other files cannot see the symbol.
2. Mismatched calling convention
Different files must use the same calling convention for arguments and return values.
3. Link order
Object file order affects symbol resolution. Put files that define symbols before or after those that use them (depending on linker).
4. Name mangling
Assembly symbols are case-sensitive. my_func and my_Func are different. C compilers add leading underscores on some platforms.
5. Duplicate symbol names
If two files define the same global symbol, the linker reports a duplicate symbol error.
Practice Questions
1. How do you make a symbol visible to other files?
Use the global directive: global my_function.
2. How do you use a symbol defined in another file?
Use the extern directive: extern my_function.
3. What is the advantage of separate assembly files?
Modularity, independent compilation, reusability, and parallel builds.
4. What tool combines multiple object files into an executable?
The linker (ld on Linux).
Challenge: Create a three-file assembly project with math, I/O, and main modules.
FAQ
{{< faq question="Can I mix assembly and C object files?" >}}
Yes. Assemble .asm to .o, compile .c to .o, and link them together. Use the C calling convention for interop.
{{< /faq >}}
{{< faq question="What is an object file?" >}}
An object file (.o) contains machine code with unresolved symbols. The linker resolves these symbols across all object files.
{{< /faq >}}
{{< faq question="Can I use include instead of separate compilation?" >}}
Yes, %include inserts the file at assembly time. But changes to any included file require reassembly of all files that include it.
{{< /faq >}}
{{< faq question="How does the linker find symbols?" >}} The linker maintains a Symbol Table from all input files. It resolves references in one file to definitions in another. {{< /faq >}}
{{< faq question="What happens if a symbol is defined in multiple files?" >}
The linker reports a duplicate symbol error unless one definition is marked weak.
{{< /faq >}}
Mini Project
Create a modular calculator with separate files for Parsing, arithmetic, and output.
; calc.asm
global add_op, sub_op, mul_op
add_op:
mov rax, rdi
add rax, rsi
ret
sub_op:
mov rax, rdi
sub rax, rsi
ret
mul_op:
mov rax, rdi
imul rax, rsi
ret
nasm -f elf64 calc.asm -o calc.o
nasm -f elf64 main.asm -o main.o
ld main.o calc.o -o calculator
What's Next
Now that you understand multi-file projects, proceed to debugging assembly.
| Topic | Description | Link |
|---|---|---|
| Debugging | GDB and debugging | {{< ref "19-debugging" >}} |
| Profiling | Performance analysis | {{< ref "20-profiling" >}} |
| Procedures | Function calls | {{< ref "10-procedures" >}} |
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro