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

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

#14 Mastering GAS A Complete Guide to the GNU Assembler

#14 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

----------------------------------

Memory Sections in GAS

.rodata Section: Storing Read-Only Data

The .rodata section is a key segment in a program’s memory layout, specifically designed for storing read-only data. This includes data that is constant and should remain unchanged during the execution of the program. The .rodata section plays a crucial role in modern low-level programming by allowing developers to efficiently manage constant values, strings, and other immutable data structures. The data in this section is not writable, and any attempt to modify it during the program’s runtime will result in an error or crash.

In this section, we will dive into the importance of the .rodata section, its practical uses, and how it interacts with the rest of the program's memory. By understanding how to effectively utilize the .rodata section, you can optimize memory usage, improve program stability, and make your code more efficient.

What Is the .rodata Section?

The .rodata section (Read-Only Data) is a portion of a program's memory reserved for data that should not be modified while the program is running. This section contains various types of constant data, including:

  • String literals: Textual strings used in the program, which are often stored as immutable constants.

  • Constant integers and floating-point numbers: Predefined constant values that are used in the program’s logic but should not be altered during execution.

  • Lookup tables and arrays: Data structures that contain values that do not change once the program starts running.

The key feature of the .rodata section is its immutability. This data is typically marked by the operating system as read-only, ensuring that any attempts to modify it will result in a program crash or access violation error. This provides an extra layer of security and integrity for critical program data.

For example, string literals like "Hello, World!" and constant values like 42 are common candidates for the .rodata section. Since these values do not change, they are placed in this section to protect them from being accidentally modified.

Why Use the .rodata Section?**

There are several key reasons for using the .rodata section in a program:

a. Memory Protection and Security

The .rodata section ensures that the data stored within it is protected from modification. This is particularly important for preventing memory corruption, which can occur when data is altered unexpectedly during execution. Since this section is marked as read-only, any attempt to modify the data will trigger a segmentation fault or a similar runtime error. This protects the program’s data from being inadvertently overwritten, thereby preventing bugs and enhancing program stability.

This feature also helps when dealing with critical data that should not be tampered with, such as encryption keys, configuration settings, and constant values that drive logic.

b. Efficiency and Memory Management

The .rodata section helps improve memory efficiency. Since the data in this section is read-only, it can be shared between different instances of the same program. If multiple processes or threads are running the same program, the operating system can map the .rodata section into memory only once. This eliminates the need to duplicate the constant data in memory for each process, saving system resources and reducing memory usage.

For example, if a program contains a string literal "Hello, World!" in the .rodata section, and multiple instances of the program are running, the operating system can share the same memory address for all instances. This results in a more memory-efficient program, especially when dealing with large, read-only data like lookup tables or large constant arrays.

c. Performance Optimization

By storing read-only data in the .rodata section, the program becomes more predictable in terms of memory access. The operating system can optimize how the read-only data is loaded into memory, possibly using cache optimization or ensuring that read-only data resides in memory regions that can be efficiently accessed. Additionally, the operating system can often map this section into memory using demand paging, which means the data is only loaded into memory when it is actually accessed, saving further resources.

Because this section is immutable, the program can take advantage of these optimizations and avoid the overhead of checking whether data has been modified. This also leads to better program startup times and reduced memory fragmentation.

d. Debugging and Maintenance

By placing constant values in the .rodata section, developers can easily identify and ensure that these values remain consistent throughout the program’s execution. If an error occurs due to the modification of a constant or string literal, the .rodata section will make it easy to track and fix the issue. Debugging becomes much easier because the developer is assured that the data in this section will not change unless explicitly modified in the code (which should never happen).

This makes the .rodata section an essential tool for maintaining clean and maintainable code, as it helps developers prevent bugs related to unintended side effects on constants and other read-only data.

Defining Data in the .rodata Section

In GAS (GNU Assembler), the .rodata section can be defined using specific assembler directives. These directives allow the programmer to define different types of constant data, such as strings, integers, and arrays, all of which are placed in the read-only data section.

a. Defining String Literals

String literals are one of the most common types of data stored in the .rodata section. In GAS, string literals can be defined using the .asciz or .string directives. The .asciz directive creates a null-terminated string (C-style string), while the .string directive creates a string without a null terminator.

Example of defining a string literal:

In this example, "Hello, World!" is a constant string that will be stored in the .rodata section. The .asciz directive tells the assembler to treat the string as a null-terminated ASCII string, which is the standard for most C-based languages.

Alternatively, if the string does not require a null terminator, the .string directive can be used:

b. Defining Constants

Another important use of the .rodata section is for defining constants such as integers, floating-point values, and other numeric constants. These constants can be defined using the .long, .quad, .float, or .double directives, depending on the data type.

Example of defining a constant integer:

Here, const_value is a constant integer that holds the value 42, and it will be stored in the .rodata section. The .long directive tells the assembler to allocate 4 bytes (32 bits) for this constant.

Example of defining a constant floating-point number:

In this case, float_const holds the value 3.14, and it will be stored as a 32-bit floating-point constant in the .rodata section.

c. Defining Constant Arrays

Arrays that hold constant values, such as lookup tables or precomputed results, are another common use for the .rodata section. Defining arrays in the .rodata section ensures that the values cannot be changed during program execution, which is especially useful for performance-critical operations like lookups and hashing.

Example of defining a constant byte array:

This defines a constant byte array that holds the values 1, 2, 3, 4, and 5. The .byte directive is used to allocate space for each byte of data, and the data will be stored in the .rodata section, making it immutable.

How the .rodata Section Fits into the Program’s Memory Layout

The .rodata section is part of the program's overall memory layout. The memory layout of a typical program is divided into several key segments:

  1. Text Segment: This is where the executable code (machine instructions) of the program is stored.

  2. Data Segment: This contains initialized variables, such as global and static variables with explicit values.

  3. Read-Only Data Segment: The .rodata section belongs here. It contains read-only data that should not be altered during program execution.

  4. BSS Segment: This section holds uninitialized global or static variables. The values of these variables are typically set to zero by the operating system at runtime.

  5. Heap: Used for dynamic memory allocation during the execution of the program.

  6. Stack: Used for storing function call information, local variables, and other runtime data.

The .rodata section typically resides after the .data section and before the heap and stack regions. This placement ensures that the program can quickly access read-only constants while preventing modification of this data.

Example of Using the .rodata Section

Here is a complete example demonstrating the usage of the .rodata section to store strings, constants, and arrays in GAS:

In this example:

  • The .rodata section contains a string literal "Welcome to GAS programming!", a constant integer 100, and a constant byte array.

  • The program uses Linux system calls to print these constants to the console, ensuring that the read-only data remains protected and immutable throughout the program’s execution.

Conclusion

The .rodata section is vital for managing read-only, immutable data in low-level programs. By using this section to store constants, strings, and other non-modifiable data, developers can improve program efficiency, prevent errors, and take advantage of memory optimizations provided by the operating system. The .rodata section ensures that the integrity of critical data is maintained, while also making the program more memory-efficient and secure.

By understanding the proper usage of the .rodata section, you can write cleaner, more efficient, and more reliable assembly programs that are optimized for modern operating systems and hardware.

Advertisements

Responsive Counter
General Counter
1000734
Daily Counter
2354