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
| Instruction | Data type/Function | Number of bytes | Supplementary notes |
|---|---|---|---|
.byte | Define 8-bit integer | 1 B | Usually used for characters, control bits |
.hword | Define 16-bit integer (half-word) | 2 B | Also called in some architectures.short |
.int/.long | Define 32-bit integer | 4 B | .intIs an alias, same effect |
.quad | Define 64-bit integer (quad-word) | 8 B | Very commonly used in AArch64 |
.float | Define IEEE-754 single-precision floating-point number (32-bit) | 4 B | Equivalent to in C languagefloat |
String definition pseudo-instruction
| Instruction | Function 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 | .rept <count> |
Function: Repeat a block of assembly code or data definition several times, suitable for initializing arrays or filling space.
Example:
1 | .rept 3 |
Equivalent to:
1 | .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 | .equ LED_BASE, 0x3F200000 |
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 immutable | Preprocessing stage text replacement |
Can be used in expressions (such as.equ val, 4+5) | Only performs text concatenation |
Used within the assembler.ifdefetc. pseudo-instructions for conditional evaluation | Can be used with#ifdefetc. in conjunction |
Function-related pseudo-instructions
| Pseudo-operations | Description of function |
|---|---|
.global | Define a global symbol |
.include | Include header file |
.if .else .endif | Control statement structure, used for conditional compilation |
if statement pseudo-operation
| Instruction | Meaning description |
|---|---|
.ifdef symbol | DeterminesymbolWhether it is defined |
.ifndef symbol | DeterminesymbolWhetherNotDefinition |
.ifc str1,str2 | Evaluate stringstr1andstr2Whether they are equal |
.ifeq expr | Evaluate expressionexprWhether the value is 0 |
.ifeqs str1,str2 | Equivalent to.ifc str1,str2 |
.ifge expr | Evaluate expressionexprWhether the value is ≥ 0 |
.ifle expr | Evaluate expressionexprWhether the value is ≤ 0 |
.ifne expr | Evaluate expressionexprwhether the value is ≠ 0 |
section-related pseudo-operations
- .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
| Flag | Meaning description |
|---|---|
a | allocatable: This section needs to be loaded into memory at runtime. |
d | GNU_MBIND section: A special binding section used by GNU. |
e | excluded: This section will not be included in the executable file or shared library. |
w | writable: This section is writable. |
x | executable: This section contains executable code. |
M | mergeable: Can be merged with other sections with the same attributes (usually used for read-only strings, etc.). |
S | string: This section contains null-terminated strings. |
G | group: This section belongs to a section group (such as COMDAT). |
T | thread-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 on
pushsectionandpopsectionthe 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 |
|
_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

Solution:
- Use spaces or use altmacro+&

- Use “\()” to represent concatenation


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 | adrp x0, foo |
- ldr pseudo-instruction
- .bss switches to bss section
- .dword/.xword 64-bit data
- name .reg register_name names a register
1 | foo w0 |
