Assemblers Are Just Different Dialects Of Assembly.
September 28, 2025
Assemblers are just different dialects of the same assembly language. In the end, the object code remains the same for a nasm source and gas source doing the same thing the same way, just different directives.
This thing is so trivial that we don’t even require gdb to verify it.
Take these sources:
This uses nasm
directives.
section .data
val dq 42 ; 42 as a 64-bit value
section .text
global _start
_start:
mov rax, [val] ; load value into rax
mov rdi, rax ; move it into rdi for exit code
mov rax, 60 ; syscall: exit
syscall
This uses gas
directives.
.data
val: .quad 42 # 42 as a 64-bit value
.text
.global _start
_start:
movq val, %rax # load value into rax
movq %rax, %rdi # move into rdi for exit code
movq $60, %rax # syscall: exit
syscall
Assemble them.
nasm -f elf64 nasm.s -o nasm.o
as gas.s -o gas.o
Stop. What do we need to verify?
- If assembler directives are just dialects, the object code should be the same.
Let’s use objdump
to disassemble both the object codes.
objdump -D nasm.o > nasm.txt
objdump -D gas.o > gas.txt
Open both the files and you will see this:
nasm.o: file format elf64-x86-64
Disassembly of section .data:
0000000000000000 <val>:
0: 2a 00 sub (%rax),%al
2: 00 00 add %al,(%rax)
4: 00 00 add %al,(%rax)
...
Disassembly of section .text:
0000000000000000 <_start>:
0: 48 8b 04 25 00 00 00 mov 0x0,%rax
7: 00
8: 48 89 c7 mov %rax,%rdi
b: b8 3c 00 00 00 mov $0x3c,%eax
10: 0f 05 syscall
gas.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <_start>:
0: 48 8b 04 25 00 00 00 mov 0x0,%rax
7: 00
8: 48 89 c7 mov %rax,%rdi
b: 48 c7 c0 3c 00 00 00 mov $0x3c,%rax
12: 0f 05 syscall
Disassembly of section .data:
0000000000000000 <val>:
0: 2a 00 sub (%rax),%al
2: 00 00 add %al,(%rax)
4: 00 00 add %al,(%rax)
...
If you rearrange the content in one of the files, you get this:
nasm.o: file format elf64-x86-64
Disassembly of section .data:
0000000000000000 <val>:
0: 2a 00 sub (%rax),%al
2: 00 00 add %al,(%rax)
4: 00 00 add %al,(%rax)
...
Disassembly of section .text:
0000000000000000 <_start>:
0: 48 8b 04 25 00 00 00 mov 0x0,%rax
7: 00
8: 48 89 c7 mov %rax,%rdi
b: b8 3c 00 00 00 mov $0x3c,%eax
10: 0f 05 syscall
gas.o: file format elf64-x86-64
Disassembly of section .data:
0000000000000000 <val>:
0: 2a 00 sub (%rax),%al
2: 00 00 add %al,(%rax)
4: 00 00 add %al,(%rax)
...
Disassembly of section .text:
0000000000000000 <_start>:
0: 48 8b 04 25 00 00 00 mov 0x0,%rax
7: 00
8: 48 89 c7 mov %rax,%rdi
b: 48 c7 c0 3c 00 00 00 mov $0x3c,%rax
12: 0f 05 syscall
Run diff
on them.
diff gas nasm
- Only the 19th line is different because GAS used rax and NASM used eax, which is a small assembler optimization.
- Line 20 is also the same except that 10/12 thing.
Conclusion
This proves that our choice to learn x64 assembly, instead of getting drowned in assemblers was a right choice and assemblers are indeed just dialects of the same assembly language.