Cover image for GNU AS

GNU AS

Words 1.4k
Views
Visitors

Timeline

Timeline

2025-09-27

init

This article introduces the basic concepts and usage of the GNU AS assembler, focusing on the syntax rules under the AArch64 architecture. It first explains the relationship between GNU AS and GCC, and compares the differences between AT&T syntax and the ARM Unified Assembly Language (UAL) format. It then details label definitions, comment styles, symbol declarations (including global and local symbols), and the use of alignment directives. In terms of data definition, the article summarizes directives for integers, floating-point numbers, and strings, and explains common operations such as .rept repeat blocks and .equ/.set constant definitions. In addition, it introduces function-related directives, conditional compilation if statement structures, and .section section definitions and their attribute flags. The overall content systematically covers the core knowledge points of the GNU assembler in ARM64 development, suitable for embedded and low-level system developers.

Reference documents:

ARM64 assembler

  • ARM’s official assembler
  • GNU AS assembler: aarch64-linux-gnu-as
  • GCC uses as as its assembler
    • AT&T: originated from Bell Labs, an assembly syntax created for developing the UNIX system (under x86, GCC outputs AT&T syntax by default)
    • ARM format: ARM’s official assembly syntax (under AArch64, GCC outputs ARM Unified Assembly Language (UAL) format by default)

Syntax

  • label: Any identifier ending with a colon is considered a label
  • Comment
    • //Indicates a comment (AArch64 also supports/* */block comments)
    • @At the beginning of a line, indicates the entire line is a comment (under AArch64, the line comment character is@, not##used to represent immediate values in AArch64)
  • Instructions, pseudo-instructions, and registers can all be uppercase or lowercase; GNU style defaults to lowercase

Symbol

Represents the address where it is located, and can also be used as a variable or function

  • Global symbol, can be declared with .global
  • Local symbol, mainly used within a local scope, with a label name starting with a number between 0-99, usually used together with the b instruction
  • f: indicates forward search
  • b: indicates backward search

Alignment directives

  • .align aligns by filling data to achieve alignment. It can fill with 0 or use the nop instruction.
    • Tells the assembler that the assembly after .align must be allocated starting from the next address divisible by 2^n
    • In the ARM64 system, the first parameter represents 2^n size

Data definition directives

Summary of integer and floating-point directives
InstructionData type / purposeByte countSupplementary notes
.byteDefine an 8-bit integer1 BUsually used for characters, control bits
.hwordDefine a 16-bit integer (half-word)2 BAlso called in some architectures.short
.int/.longDefine a 32-bit integer4 B.intIs an alias, same effect
.quadDefine a 64-bit integer (quad-word)8 BVery commonly used in AArch64
.floatDefine an IEEE-754 single-precision floating-point number (32-bit)4 BEquivalent to the one in Cfloat
String definition pseudo-instruction
InstructionDescription
.ascii "str"Insert the string as-is, without automatically adding\0, suitable for non-C-style strings
.asciz "str"At the end of the string automatically append a null character\0, suitable for C strings (recommended)
.rept … .endr: Repeat block definition

Syntax:

123
.rept <count>  <内容>.endr

Purpose: Repeat a section of assembly code or data definitions several times, suitable for initializing arrays or filling space.

Example:

123
.rept 3    .long 0.endr

Equivalent to:

123
.long 0.long 0.long 0
.equ / .set: Constant definition (assignment operation)

These two directives are completely equivalent, just with slightly different syntax styles.
.equ

1
.equ abcd, 0x45

Make abcd a constant macro definition with value 0x45.
.set

1
.set abcd, 0x45

Same effect, also defines abcd as 0x45.

Typical uses: for defining register addresses, constant bit masks, etc.
Common usage example (combining .equ and .rept):

123456
.equ LED_BASE, 0x3F200000.section .data.rept 4    .int LED_BASE.endr

Indicates filling the LED_BASE address 4 times, each time 4 bytes, for a total of 16 bytes.

.equwith C’s#definethe difference:

.equ/.set#define
Assigned during assembly, value is immutableText substitution during preprocessing
Can be used in expressions (e.g.,.equ val, 4+5Only text concatenation
Used internally by the assembler.ifdefand other pseudo-instructions for conditional checksCan be used with#ifdefetc. in combination
Pseudo-operationDescription
.globalDefine a global symbol
.includeInclude header file
.if .else .endifControl statement structure for conditional compilation
if statement pseudo-operation
InstructionMeaning description
.ifdef symbolDeterminesymbolWhether defined
.ifndef symbolDeterminesymbolWhethernotDefinition
.ifc str1,str2Check stringstr1andstr2whether equal
.ifeq exprEvaluate expressionexprwhether the value is 0
.ifeqs str1,str2is equivalent to.ifc str1,str2
.ifge exprEvaluate expressionexprwhether the value is ≥ 0
.ifle exprEvaluate expressionexprwhether the value is ≤ 0
.ifne exprEvaluate expressionexprwhether the value is not equal to 0
  • .section indicates which section the subsequent assembly code will be linked into, such as code section, data section, etc.
  • Each section starts with a section name and ends with the next section name or the end of the file.
1
.section name, "flags"

Flags can be added after it to indicate the attributes of the section.

FlagMeaning description
aallocatable: This section needs to be loaded into memory at runtime.
dGNU_MBIND section: A special binding section used by GNU.
eexcluded: This section will not be included in executable files or shared libraries.
wwritable: This section is writable.
xexecutable: This section contains executable code.
Mmergeable: Can be merged with other sections with the same attributes (usually used for read-only strings, etc.).
Sstring: This section contains null-terminated strings.
Ggroup: This section belongs to a section group (e.g., COMDAT).
Tthread-local-storage: This section is used for thread-local storage (TLS).
?unspecified group: This section belongs to the group of the previous section (if any).

Example:

1
.section ".idmap.text","awx"

.pushsection <name>
Place the following code or datainto the specified section, and at the same timesave the current section state

.popsection
representsend the previous push, andrestore the original section

  • Use in pairs

  • The effect is only onpushsectionandpopsectionthe code between …, and has no effect on other code.

  • The rest of the code still belongs to the original section, for example.textor.data

12345678910
    .text    .globl _start_start:    nop             // in the default .text section    .pushsection .mydata, "a"    .long 0x12345678  // is inserted into the .mydata section    .popsection    nop             // returns to the .text section again

_startand twonopboth belong to.textsection;

.long 0x12345678is inserted into the custom.mydatasection.

Macro
  • .macro and .endm form a macro
  • .macro is followed by the macro name, and then the macro parameters.
  • To use parameters in a macro, you need to add the prefix ""
1
.macro plus1 p, p1

defines a macro named plus1 with two parameters p and p1

Using parameters in a macro requires a prefix; “\p” represents the first parameter, “\p1” represents the second parameter

  • When defining macro parameters, you can set an initial value.
1
.macro reserve_str p1=0 p2

The first parameter p1 has an initial value, 0. In this case, you can use reserve_str a,b or reserve_str, b to call this macro

Possible problems when using parameters in macros
Possible problems when using parameters in macros

Solution:

  • Use spaces or use altmacro+&

Use spaces or use altmacro+&
Use spaces or use altmacro+&

  • Use “\()” to indicate concatenation

Use "()" to indicate concatenation
Use "()" to indicate concatenation

An example of the Linux kernel using "()"
An example of the Linux kernel using "()"

ARM64-specific features

ARM64 compilation options
  • -EB: for big-endian CPUs, -EL: for little-endian CPUs
  • -mabi: specify ABI mode, ilp32 for ELF32, lp64 for ELF64, default is lp64
  • -mcpu=processor+extension: specify CPU model, e.g., cortex-a72
  • -march=, used to specify the supported architecture, e.g., armv8.2-a
  • Extensions supported by ARM64, see GNU assembler as_v2.34 Chapter 9.1.2
Special characters
  • //Indicates a comment
  • @In AArch64, indicates a line comment;#Does not indicate a comment, only used as an immediate prefix
  • :lo12:Indicates the low 12 bits (e.g.,#:lo12:foo
12
adrp x0, fooldr x0, [x0, #:lo12:foo]
  • ldr pseudo-instruction
  • .bss switches to the bss section
  • .dword/.xword 64-bit data
  • name .reg register_name names a register
1
foo .req w0
Loading comments…