Keywords: Linux Assembly Development | GNU Assembler | NASM Comparison
Abstract: This article provides an in-depth exploration of two primary tools for assembly language development in Linux systems: the GNU Assembler (GAS) and NASM. By comparing AT&T and Intel syntax differences, along with concrete code examples, it details the complete process of compiling, linking, and running assembly programs. Covering both 32-bit and 64-bit architectures, the article offers practical commands and resource links to help developers quickly master Linux assembly programming.
Overview of Assembly Development Tools
When developing assembly language programs in Linux environments, developers primarily choose between two mainstream tools: the GNU Assembler (GAS) and NASM. These tools have distinct characteristics, with the most notable difference being their syntax formats. GAS uses AT&T syntax, where operand order is source, destination; NASM employs Intel syntax with the reverse order: destination, source. This syntactic variation affects not only coding habits but also code readability and portability.
Practical Usage of GNU Assembler (GAS)
As part of the GNU toolchain, GAS is typically pre-installed on most Linux distributions. Developers can view complete usage instructions via the man as command. While direct use of as for assembly and ld for linking is possible, a more common approach leverages GCC as a front-end tool. For example, consider this simple x86-64 assembly program:
.section .rodata
.globl hello
hello:
.string "Hello, world!"
.text
.global main
main:
push %rbp
mov %rsp, %rbp
mov $hello, %edi
call puts
mov $0, %eax
leave
retAfter compiling with gcc hello.s -no-pie -o hello, running ./hello outputs "Hello, world!". For Position-Independent Executables (PIE), RIP-relative addressing is required: lea hello(%rip), %rdi and call puts@plt.
Application of NASM Assembler
NASM, another popular assembler, can be installed on Ubuntu via apt-get install nasm. Its basic compilation command is: nasm -felf32 -g -Fdwarf file.asm -o file.o, with the resulting object file linkable using gcc -m32 or ld -melf_i386. For 64-bit programs, the -felf64 parameter is necessary. NASM's Intel syntax aligns more closely with traditional assembly textbooks, potentially making it easier for developers migrating from other platforms.
Architectural Differences and Compatibility Considerations
Significant distinctions exist between 32-bit and 64-bit assembly programming. 32-bit code uses different calling conventions and lacks RIP-relative addressing support. For instance, parameter passing in 32-bit systems often involves stack operations: push $hello. Additionally, developers must consider choices between absolute and relative addressing, particularly when creating PIE executables. GCC's -S option can compile C code into assembly, serving as an effective method for learning how compilers generate assembly instructions.
Development Recommendations and Resource Guidance
For beginners, starting with simple "Hello World" programs is advised to gradually understand fundamental assembly concepts. The AT&T syntax guide (https://stackoverflow.com/tags/att/info) and Intel syntax guide (https://stackoverflow.com/tags/intel-syntax/info) are essential references. Furthermore, the Assembly-Intro tutorial (http://asm.sourceforge.net/intro/Assembly-Intro.html) and x86 tag wiki (https://stackoverflow.com/tags/x86/info) provide deeper learning materials. In practical development, tool selection should align with project requirements and personal preferences, with attention to subtle differences arising from syntax and architecture variations.