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

ARM V7内联汇编:C变量与寄存器值互传问题求助

ARMv7内联汇编实现C变量与r0-r2的双向传递问题解决

你的核心问题是内联汇编的操作数方向搞反,且拆分的独立asm块被编译器优化/重排,导致寄存器加载了意外值(比如固定12)。以下是具体分析和修复方案:

问题根源

  1. 操作数方向错误:你写的asm("mov r0, %0" : "=r"(func))是把r0的值写入func变量(输出约束),但你实际需要的是把func的值加载到r0(输入约束),完全搞反了数据流向。
  2. 独立asm块的顺序风险:多个单独的asm语句没有约束执行顺序,编译器可能会调整指令位置,甚至优化掉看似无用的mov指令,导致寄存器被其他代码覆盖出现固定值。
  3. 缺少volatile和破坏寄存器声明:未加volatile可能让编译器优化掉汇编块,未声明被修改的寄存器(如r7)会导致编译器错误地复用这些寄存器。

修复方案(双向传递:变量→寄存器→变量)

如果需要实现C变量值传入寄存器,同时系统调用后寄存器值写回C变量,可以将所有汇编指令放到一个asm volatile块中,正确指定输入输出约束:

#include "syscalls.h"

void syscall_create_thread(void (*f) (void *), void * args, unsigned int arg_size,
                           unsigned int *thread_id) {
    unsigned int func = (unsigned int)f;
    unsigned int arguments = (unsigned int)args;
    unsigned int arg_size_copy = arg_size;

    asm volatile (
        "mov r7, #" TOSTRING(SYSCALL_ID_CREATE_THREAD) "\n\t"
        "svc #0"
        // 输出约束:SVC执行后,将r0/r1/r2的值写回对应变量
        : "=r"(func), "=r"(arguments), "=r"(arg_size_copy)
        // 输入约束:将变量值加载到r0/r1/r2(%0对应r0,%1对应r1,%2对应r2)
        : "0"(func), "1"(arguments), "2"(arg_size_copy)
        // 破坏寄存器列表:告诉编译器这些寄存器的值会被修改
        : "r7", "memory"
    );

    // 示例:将r0返回的线程ID输出
    if (thread_id != NULL) {
        *thread_id = func;
    }
}

简化方案(单向传递:变量→寄存器)

如果只需要把C变量的值加载到r0-r2,不需要写回,可以直接指定寄存器输入约束,代码更简洁:

#include "syscalls.h"

void syscall_create_thread(void (*f) (void *), void * args, unsigned int arg_size) {
    asm volatile (
        "mov r7, #" TOSTRING(SYSCALL_ID_CREATE_THREAD) "\n\t"
        "svc #0"
        :  // 无输出约束
        // 直接指定将变量值放入r0/r1/r2
        : "r0"((unsigned int)f), "r1"((unsigned int)args), "r2"(arg_size)
        : "r7", "memory"
    );
}

关键说明

  • asm volatile:强制编译器不优化、不重排该汇编块,保证指令按顺序执行。
  • 输入输出约束:"=r"(var)表示将寄存器值写入var(输出);"0"(var)表示使用和第0个输出约束相同的寄存器,将var的值加载到该寄存器(输入)。
  • 破坏列表:"r7"声明r7被修改,"memory"告诉编译器系统调用可能修改内存,避免编译器缓存变量到寄存器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 08:15:13