Timeline
Timeline
2025-09-27
init
This article introduces the basic and extended modes of GCC inline assembly, discusses in detail its core mechanisms such as syntax format, input/output constraints, clobber lists, and goto jumps, and summarizes advanced usage and common pitfalls for implementing low-level optimization operations like memcpy, memset, and system register read/write by combining C language macros and statement expressions.
Reference documents:
Inline Assembly (Inline Assembly Language) embeds assembly code in C language
Purpose:
- Optimization: Optimize specific critical code (time-sensitive)
- C language needs to access certain special instructions to implement special functions, such as memory barrier instructions
Two modes of inline assembly
- Basic inline assembly
- Extended inline assembly
Basic inline assembly
Format:
1 | asm asm-qualifiers(AssemblerInstructions) |
asm keyword: indicates this is a GNU extension
Qualifiers
- volatile: usually not needed in basic inline assembly
- inline: inline, the asm assembly code will be as small as possible
Assembly code block (AssemblerInstructions)
The GCC compiler treats inline assembly as a string
GCC compilation does not parse and analyze inline assembly
Multiple assembly instructions need to use “\n\t” for line breaks
GCC’s optimizer can move the position of assembly instructions. If you need to preserve the order of assembly instructions, it is best to use multiple inline assembly blocks

Extended inline assembly

- Format
- asm keyword: indicates this is a GNU extension
- Qualifiers (asm-qualifiers)
- volatile: used to disable GCC optimization
- inline, the asm code will be as small as possible
- goto will jump to the C label after the inline assembly ends

Output section:
Used to describe in the instruction sectionC variables that can be modifiedand constraints
- Each output constraint usually starts with “=”, followed by a letter indicating the operand type, and then the constraint on variable binding
- The output section usually uses “=” or “+” as output constraints, where “=" indicates that the modified operand is write-only (the original value is dead before assembly execution, and can be written to a register)”,“+" indicates that the modified operand is read-write (the initial input value will be preserved and used)”
- The output section can be empty
1 | "=/+" + 约束修饰符 + 变量 |
Commonly used constraint modifiers include:
- ‘r’ A register operand is allowed provided that it is in a general register.
Input section
Used to describe in the instruction sectionC variables that can only be readand constraints
- The parameters described in the input section are read-only. Do not attempt to modify the contents of the input section parameters, because the GCC compiler assumes that the contents of the input section parameters are consistent before and after the inline assembly
- You cannot use “=” or “+” constraints in the input section, otherwise the compiler will report an error
- The input section can be empty
Clobber section (Clobbers)
- The assembly code maymodify registers other than the outputs。
- If not told to the compiler, it will cause the compiler to think these registers remain unchanged, which may eventually lead to errors or unpredictable behavior.
- Clobber is also a kind ofmemory barriers(especially
"memory"), ensuring the compiler does not reorder or cache variables.
| Name | Function |
|---|---|
"x0","x1", … | General-purpose registers are modified |
"cc" | Condition code register (flags) is modified |
"memory" | Assembly accesses memory, ensuring the compiler flushes registers to memory and reloads them |
"redzone" | Using stack space in the x86-64 redzone area |
- “memory” tells the GCC compiler that the inline assembly instruction changes values in memory, forcing the compiler to store all cached values before executing the assembly code and reload them after, with the purpose of preventing compiler reordering
- “cc” indicates that the inline assembly code modifies the flags related to the status register
Not allowed to write in the clobber list Stack pointer register (esp/rsp)。
Do not list output registers repeatedly.
The four possible cases can be combined, separated by commas.
- Parameter representation in the instruction section
- %0 corresponds to the first parameter in the output/input section, %1 represents the second parameter


Constraint modifiers for the output and input sections

Constraint modifiers for the output and input sections - General

Constraint modifiers for the output and input sections - ARM64

Assembly symbol name to replace the % prefix
%[name]→ Reference constraint variable%w[name]→ Reference Lower 32-bit register(e.g.w0, w1)%x[name]→ Reference Complete 64-bit register(e.g.x0, x1)

Experiment 1: Implementing a simple memcpy function


Traps and pitfalls
- GDB cannot single-step debug inline assembly
- Modifiers for the output and input sections cannot be used incorrectly, otherwise the program will run incorrectly
Experiment 3: Implementing the memset function using inline assembly

Advanced usage of inline assembly: combining with macros
- Tip 1: Uses the ‘#’ operator in C. In macros with parameters, the ‘#’ operator acts as a preprocessor operator that can convert a token into a string

1 |
This macro can be used to generate multiple atomic operation functions:
1 | ATOMIC_OP(add, "addl") |
This will expand to:
1 | static inline void atomic_add(int i, atomic_t *v) { |
Noteasm_opis a macro parameter,which will be replaced with the value you provide during macro expansion, and a string literal (with double quotes) must be passed when calling, such as"addl", so that it can be directly embedded into the assembly template as an instruction string:
1 | ATOMIC_OP(add, "addl") |
After macro expansion, it is:
1 | __asm__ __volatile__( |
If incorrectly passed without quotes
addl, it will be treated as an identifier rather than a string, and after expansion it becomesaddl "%1, %0"causing an assembly syntax error.
##name—— Token pasting operator
Directly concatenate the macro parameter and the surrounding identifiers to form a new identifier (not a string).
Often used to generate variable names, function names, etc.
1 |
|
Experiment 4: Using a combination of inline assembly and macros


Experiment 5: Implementing macros for reading and writing system registers


Here we useGNU C’s statement expression Syntax:
({ ... })What is
This is a GNU extension, not standard C.
It allows a block of code to execute like a statement, and alsoreturn a value。
Syntax rules:
({ statement1; statement2; ...; expression; })
The last one in the code block expression(without a semicolon) is the return value.

Inline assembly: goto
The goto template for inline assembly, which can jump to C language label tags

- The output section of the Goto template must be empty
- Added a gotolabels section, which lists the C language labels that are allowed to jump to

Experiment 6: Inline assembly of goto template


%l[label]is in GCC inline assemblyasm gotoa special syntax, indicating a jump to a label in C codelabel。
Detailed explanation:
%l[...]is to tell the compiler that this is alabel symbol(label), rather than a regular register or immediate value.labelis the label name you defined in the C code, such as in your codelabel:。asm gotoallows assembly code to directly jump to a label in C code via conditional jump, implementing conditional branching.
