Cover image for GNU AS

GNU AS

Words 1.3k
Views
Visitors

Timeline

Timeline

2025-09-27

init

This article introduces the syntax and pseudo-instruction usage of the GNU AS assembler under the ARM64 (AArch64) architecture, covering labels, comments, symbols (global and local), alignment pseudo-instructions, data definition pseudo-instructions (integers, floating-point numbers, strings), repeat block definitions (.rept/.endr), constant definitions (.equ/.set), function-related pseudo-instructions, conditional compilation pseudo-instructions, and section-related pseudo-instructions (.section, .pushsection/.popsection), and compares the differences between AT&T syntax and ARM official assembly syntax.

Reference documents:

ARM64 assembler

  • ARM’s official assembler
  • GNU AS assembler: aarch64-linux-gnu-as
  • gcc uses as as its assembler
    • AT&T: Assembly syntax originating from Bell Labs, created for developing the UNIX system (gcc defaults to outputting AT&T syntax under x86)
    • ARM format: ARM official assembly syntax (gcc defaults to outputting ARM Unified Assembly Language (UAL) format under AArch64)

Syntax

  • label: Any identifier ending with a colon is considered a label
  • Comment
    • // indicates a comment
    • # at the beginning of a line, indicates commenting out the entire line
  • Instructions, pseudo-instructions, and registers can all be uppercase or lowercase; the 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, starting with a number between 0-99 as the label name, usually used in conjunction with the b instruction
  • f: instructs the compiler to search forward
  • b: instructs the compiler to search backward

Alignment pseudo-instruction

  • .align alignment, fills data to achieve alignment. Can be filled with 0 or use the nop instruction.
    • Tells the assembler that the assembly following .align must start allocation from the next address divisible by 2^n
    • In the ARM64 system, the first parameter represents the 2^n size

Data definition pseudo-instruction

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

Syntax:

1
2
3
.rept <count>
<内容>
.endr

Function: Repeat a block of assembly code or data definition several times, suitable for initializing arrays or filling space.

Example:

1
2
3
.rept 3
.long 0
.endr

Equivalent to:

1
2
3
.long 0
.long 0
.long 0
.equ / .set: Constant definition (assignment operation)

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

1
.equ abcd, 0x45

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

1
.set abcd, 0x45

Same effect, also defines abcd as 0x45.

Typical use: Used to define register addresses, constant bitmasks, etc.
Common usage example (combining .equ and .rept):

1
2
3
4
5
6
.equ LED_BASE, 0x3F200000

.section .data
.rept 4
.int LED_BASE
.endr

Means filling the LED_BASE address 4 times, 4 bytes each time, totaling 16 bytes.

.equCompared with C’s#define:

.equ/.set#define
Assembly stage assignment, value is immutablePreprocessing stage text replacement
Can be used in expressions (such as.equ val, 4+5Only performs text concatenation
Used within the assembler.ifdefetc. pseudo-instructions for conditional evaluationCan be used with#ifdefetc. in conjunction
Pseudo-operationsDescription of function
.globalDefine a global symbol
.includeInclude header file
.if .else .endifControl statement structure, used for conditional compilation
if statement pseudo-operation
InstructionMeaning description
.ifdef symbolDeterminesymbolWhether it is defined
.ifndef symbolDeterminesymbolWhetherNotDefinition
.ifc str1,str2Evaluate stringstr1andstr2Whether they are equal
.ifeq exprEvaluate expressionexprWhether the value is 0
.ifeqs str1,str2Equivalent to.ifc str1,str2
.ifge exprEvaluate expressionexprWhether the value is ≥ 0
.ifle exprEvaluate expressionexprWhether the value is ≤ 0
.ifne exprEvaluate expressionexprwhether the value is ≠ 0
  • .section indicates which section the following assembly 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 afterwards to indicate the section’s attributes

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 the executable file or shared library.
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 (such as 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>
insert the following code or datainto the specified section, whilesaving the current section state

.popsection
Representsending the previous push, andrestoring the original section

  • used in pairs

  • Its effect is only onpushsectionandpopsectionthe code in between, and has no effect on other code.

  • The rest of the code still belongs to the original section, such as.textor.data

1
2
3
4
5
6
7
8
9
10
    .text
.globl _start
_start:
nop // in the default .text section

.pushsection .mydata, "a"
.long 0x12345678 // Inserted into the .mydata section
.popsection

nop // Back to the .text section

_startand twonopboth belong to.textsection;

.long 0x12345678was inserted into the custom.mydatasection.

Macro
  • .macro and .endm form a macro
  • After .macro comes the macro name, followed by 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

  • A default value can be set when defining macro parameters
1
.macro reserve_str p1=0 p2

The first parameter p1 has a default value, 0. At this time, 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 represent concatenation

Use "()" to represent concatenation
Use "()" to represent concatenation

Example of Linux kernel using "()"
Example of Linux kernel using "()"

ARM64-specific features

ARM64 compilation options
  • -EB: for big-endian CPUs, -EL: for little-endian CPUs
  • -mabi: Specifies ABI mode, ilp32 for ELF32, lp64 for ELF64, default is lp64
  • -mcpu=processor+extension: Specifies CPU model, e.g., cortex-a72
  • -march=: Used to specify 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
  • # indicates a comment if at the beginning of a line, can also indicate an immediate value if not at the beginning of a line
  • :low12 indicates the lower 12 bits
1
2
adrp x0, foo
ldr x0, [x0, #:lo12:foo]
  • ldr pseudo-instruction
  • .bss switches to bss section
  • .dword/.xword 64-bit data
  • name .reg register_name names a register
1
foo .req w0