---
title: 内联汇编
url: https://doc.liz6.com/rust/07-unsafe-rust/03-inline-assembly
locale: zh
area: rust
tags:
- rust
- Unsafe Rust
date: 2026-06-30
modified: 2026-06-30
description: asm! 宏让 Rust 直接嵌入目标机器的汇编指令——constraints 描述寄存器的输入/输出关系,clobbers 声明哪些寄存器被破坏。每条汇编模板都是 per-arch 的(x86_64 和 ARM64 写法完全不同),本质上是对编译器优化的一堵"请不要跨过这行做优化"的墙。
---

# 内联汇编

> `asm!` 宏让 Rust 直接嵌入目标机器的汇编指令——constraints 描述寄存器的输入/输出关系,clobbers 声明哪些寄存器被破坏。每条汇编模板都是 per-arch 的(x86_64 和 ARM64 写法完全不同),本质上是对编译器优化的一堵"请不要跨过这行做优化"的墙。

## asm! 基础

```rust
use std::arch::asm;
let x: u64;
unsafe { asm!("rdtsc", out("rax") _, out("rdx") _, lateout("rax") x); }
// TSC (Time Stamp Counter) = EDX:EAX
// out("rax") _  — upper 32 bits, value discarded (_)
// out("rdx") _  — lower 32 bits in rdx, discarded
// lateout("rax") x — value combined in x
```

`asm!` 是 Rust 1.59+ 的新宏（取代旧的 `llvm_asm!`）。编译时检查约束的正确性——寄存器冲突、invalid operand、type mismatch 都会在编译期报告。

## Constraints: 输入输出规范

```rust
let mut a: u64 = 4;
let b: u64 = 4;
unsafe {
    asm!(
        "add {0}, {1}",              // {0} = a, {1} = b
        inlateout(reg) a,            // a: 输入+输出, 不与输入共享寄存器
        in(reg) b,                   // b: 纯输入
    );
}
```

- `in(reg)`: 输入，编译器分配寄存器，加载值
- `out(reg)`: 输出，读取最终值
- `inout(reg)`: 输入+输出
- `lateout(reg)`: 输出，不与输入共享寄存器（用于输入寄存器被 clobber 的场景）
- `inlateout(reg)`: 输入+输出，不与输入共享寄存器

## Clobbers: 哪些寄存器被修改

`out` 和 `lateout` 自动标记对应寄存器为 clobbered。但如果调用了其他函数，需要标记整个 ABI 的 clobber 集合：

```rust
unsafe {
    asm!(
        "call my_function",
        clobber_abi("C"),            // 所有 C calling convention 的 caller-saved 寄存器被标记 clobbered
    );
}
```

## per-arch 条件编译

```rust
#[cfg(target_arch = "x86_64")]
unsafe { asm!("rdtsc", ...); }

#[cfg(target_arch = "aarch64")]
unsafe { asm!("mrs {}, cntvct_el0", out(reg) x); }  // ARM64 的 cycle counter
```

## Options

```rust
asm!("nop", options(nomem, nostack, preserves_flags));
// nomem:    不读写内存 (编译器可以不刷新缓存)
// nostack:  不 push/pop 栈
// preserves_flags: 不修改 EFLAGS/RFLAGS
// pure:     无副作用 (可被优化消除)
// readonly: 只读内存
```

## 参考

- **Rust Reference**: inline assembly
- **Rust By Example**: asm

*Keywords: asm!, inline assembly, constraints, clobbers, lateout, clobber_abi, per-arch asm*
