Logo
Articles Compilers Libraries Books MiniBooklets Assembly C++ Linux Others Videos
Advertisement

Article by Ayman Alheraki on January 11 2026 10:37 AM

#8 Mastering GAS A Complete Guide to the GNU Assembler

#8 Mastering GAS: A Complete Guide to the GNU Assembler

Series for explaining and teaching GNU GAS Assembler using AT&T syntax – all codes are reviewed and tested daily on
Fedora Linux 42
GNU Assembler version 2.44-6

 

Writing a Simple Assembly Program Using GAS

In this section, we will guide you step-by-step through the process of writing, assembling, and running a simple assembly program using GAS (GNU Assembler). Assembly programming allows developers to write code that interacts directly with the CPU, providing fine-grained control over how a program is executed. The example we will use here is a ”Hello, World!” program written for the x86 architecture. However, the principles outlined here can be applied to other architectures as well.

This section will cover the basics of assembly syntax, register usage, system calls, and provide hands-on experience in assembling and linking a simple program.

Setting Up the Development Environment

Before diving into writing the program, let's ensure that your environment is properly set up for compiling and running assembly code.

  • Installing the Necessary Tools

You will need several tools to assemble and run your program. These are typically part of the GNU toolchain, which includes the assembler (as), the linker (ld), and optional tools like the debugger (gdb) for debugging.

– Linux/Unix: The necessary tools (GAS, ld, and gdb) are usually included by default in most Linux distributions. You can install them using package managers like apt or yum:

 

– MacOS: For MacOS, you can install the required tools through Xcode Command Line Tools by running:

– Windows: On Windows, you can use Cygwin or MinGW to emulate a Linux-like environment and use the GNU assembler tools. Both packages are available online and come with the necessary tools.

After installing the tools, you will be ready to begin writing assembly code.

Understanding the Structure of an Assembly Program

A simple assembly program typically consists of two major sections: the data section and the

text section. Each section serves a different purpose:

  • Data Section

This section is where variables, constants, and data structures are declared. In assembly language, you typically store any strings, numbers, or buffers here that will be accessed or manipulated during the program's execution.

  • Text Section

The text section contains the actual instructions that the processor will execute. These are the commands written in assembly that will be translated to machine code. It is the place where the logic of the program resides.

In addition to the data and text sections, there are also directives that help with the organization of the code, such as defining entry points for the program.

Here’s an example of a simple assembly program structure:

 

Writing a Simple ”Hello, World!” Program

Let’s now write a simple ”Hello, World!” program in x86 assembly using GAS.

 

Explanation of the Code

  • Data Section

 

  • .section .data: The data section is where all the data—like constants, strings, and variables—are declared. The .data directive tells the assembler that the following lines will define static data elements.

  • message:: This is a label representing the memory address where the string

"Hello, World!" will be stored.

  • .asciz "Hello, World!": This defines a null-terminated ASCII string.

The .asciz directive adds a zero byte (0x00) at the end of the string, which is necessary to signify the end of the string in C-like systems.

  • Text Section

     

  • .section .text: This section is where the executable code resides. The text section contains the actual assembly instructions that the CPU will execute.

  • .globl start: This line makes the label start globally visible, marking it as the entry point of the program. This is where the execution begins.

  • Syscall for Printing the Message

 

  • mov $4, %eax: This sets the EAX register to the value 4, which corresponds to the system call number for sys write. The sys write system call is used to output data to a file or terminal.

  • mov $1, %ebx: The EBX register is set to 1, representing the file descriptor for standard output (stdout).

  • mov $message, %ecx: This sets the ECX register to the address of the string

"Hello, World!". This tells the kernel where to find the message.

  • mov $13, %edx: The EDX register is set to 13, which is the length of the string

"Hello, World!".

  • int $0x80: This triggers a software interrupt that invokes the kernel to perform the system call. In this case, it will execute the sys write system call to print the string to the screen.

  • Syscall for Exiting the Program

     

  • mov $1, %eax: The EAX register is set to 1, corresponding to the system call number for sys exit, which is used to terminate the program.

  • xor %ebx, %ebx: The EBX register is cleared by using the xor instruction. This sets the exit code of the program to 0, which usually means a successful exit.

  • int $0x80: This triggers the system call to exit the program.

Assembling and Linking the Program

Once the assembly code is written, the next step is to convert the human-readable assembly code into machine code. This process involves two main steps: assembling and linking.

  • Assembling the Code

The first step is to assemble the source code into an object file. This is done using the

GNU assembler (**as)**.

To assemble the code, open a terminal and run the following command:

Here:

  • hello.s is the assembly source file.

  • hello.o is the object file that will be produced after the assembly step.

The object file (hello.o) contains machine code but is not yet executable. It must be linked before running.

  • Linking the Object File

Next, you will use a linker (in this case, ld) to combine the object file into an executable program.

To link the object file and create an executable, use the following command:

This command tells the linker (ld) to:

  • Combine the object file hello.o into an executable named hello.

  • The resulting executable is now ready to be run.

Running the Program

Now that the program is assembled and linked, you can execute it. Use the following command to run the program:

If everything is set up correctly, you should see the following output:

This demonstrates a simple interaction between your assembly code and the operating system: you wrote assembly instructions that used a system call (sys write) to print a message to the terminal.

Conclusion

This section introduced you to the basics of writing assembly programs using the GNU Assembler (GAS). You learned how to:

  • Write simple assembly code using basic instructions and system calls.

  • Structure your code into data and text sections.

  • Assemble the code and link the resulting object file to create an executable.

  • Use system calls to interact with the operating system and perform tasks like printing output and exiting the program.

Mastering these fundamentals is essential for anyone wishing to understand how low-level programming works, how programs interact with hardware, and how assembly language can be used to optimize software for performance or for specialized hardware environments.

Advertisements

Responsive Counter
General Counter
1000727
Daily Counter
2347