汇编 (Assembly)
Zig 允许直接在 Zig 源代码中嵌入汇编代码。这使得可以进行低级优化和硬件交互。
内联汇编 (Inline Assembly)
使用 asm 关键字可以插入汇编指令。
const std = @import("std");
pub fn add_two_numbers(a: i32, b: i32) i32 {
var result: i32 = undefined;
asm volatile ("add %[res], %[a], %[b]"
: [res] "=r" (result) // 输出:将结果写入 %res 对应的寄存器
: [a] "r" (a), [b] "r" (b) // 输入:%a, %b 对应的寄存器分别从 a, b 获取值
: // 没有 clobbers
);
return result;
}
test "add with asm" {
try std.testing.expect(add_two_numbers(5, 7) == 12);
}
输出约束 (Output Constraints)
输出约束指定了汇编代码如何将结果写入 Zig 变量,通常与寄存器或内存位置绑定。
"=r": 写入通用寄存器。"=m": 写入内存。
输入约束 (Input Constraints)
输入约束指定了 Zig 变量如何提供给汇编代码。
"r": 从通用寄存器读取。"m": 从内存读取。"0": 与第 0 个输出操作数使用相同的寄存器。
破坏列表 (Clobbers)
破坏列表(Clobbers)指定了汇编代码会修改但未作为显式输出列出的寄存器。编译器需要知道这些信息以正确生成代码。
全局汇编 (Global Assembly)
使用 pub extern "asm" fn 可以定义一个纯汇编函数,其整个函数体由汇编代码组成。
pub extern "asm" fn _start() noreturn {
asm volatile (
\ mov $0x0, %rbp
\ mov $0x0, %rsp
\ call main
\ mov $0x3c, %rax # syscall number for exit
\ xor %rdi, %rdi # exit code 0
\ syscall
);
}
另请参阅:
- Builtin Functions (内置函数)