You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust内联汇编调用write系统调用报错:*const str类型不可用

Rust内联汇编调用write系统调用的问题解决

我尝试在Rust中用内联汇编执行write系统调用,重现HelloSilicon项目的Hello World示例,但传入字符串切片引用时出现矛盾错误:

cannot use value of type `*const str` for inline assembly
only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly

我的代码:

use std::arch::asm;

fn main() {
    let msg = "Hello World!\n";
    let len = msg.len();
    unsafe {
        asm!(
            "mov X0,  #1",     // specify stdout
            "adr X1,  {msg}",  // point to message
            "mov X2,  {len}",  // specify message length
            "mov X16, #4",     // specify syscall number for 'write'
            "svc #0x80",       // syscall
            msg = in(reg) msg,
            len = in(reg) len,
       );
    }
}

运行环境:MacOS v13.6,M1芯片(Armv8.5-a)


问题解答

1. 更合适的指针类型

*const str是胖指针,包含指向字符串的指针和长度两个字段,内联汇编无法直接处理这种复合类型。你需要将其转换为指向字节的裸指针*const u8,用msg.as_ptr()即可获取字符串字面量的起始字节地址,这是汇编能接受的有效指针类型。

2. 忽略的其他问题

  • 系统调用号错误:MacOS ARM64的write系统调用号不是4,而是0x2000004(MacOS的系统调用号都带有0x2000000前缀)。
  • 指令使用错误:adr X1, {msg}是错误的,adr用于获取代码段中标签的地址,但你已经把msg的指针放到寄存器里了,直接用mov X1, {msg}即可加载指针值。
  • syscall触发指令错误:MacOS ARM64上触发系统调用用svc #0,而不是svc #0x80(后者是x86架构的用法)。
  • 寄存器约束优化:可以直接指定寄存器,避免额外的mov指令,让汇编更高效。

修正后的代码:

use std::arch::asm;

fn main() {
    let msg = "Hello World!\n";
    let len = msg.len();
    unsafe {
        asm!(
            "mov X16, #0x2000004", // MacOS ARM64 write系统调用号
            "svc #0",              // 触发系统调用
            in("x0") 1,            // stdout文件描述符
            in("x1") msg.as_ptr(), // 消息起始地址
            in("x2") len,          // 消息长度
        );
    }
}

内容的提问来源于stack exchange,提问作者Max Taggart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 01:30:09