【问题标题】:Work with array in gcc inline assembler (ARM)在 gcc 内联汇编器 (ARM) 中使用数组
【发布时间】:2012-03-16 10:13:56
【问题描述】:

我遇到了一些内联汇编代码的问题。我正在尝试将本地静态数组中的项目加载到 ARM 平台上的寄存器中。不幸的是,我不知道如何告诉 GCC 它应该将数组上的指针传递给寄存器。该寄存器将用于间接访问数组。

// should return argv[1]
int test() {
    int argv[4] = {4, 3, 2, 1};
    int out;

    __asm__ volatile (
        "ldr r0, %[ARGV]" "\n\t"
        "mov r1, #4" "\n\t"
        "ldr r2, [r0, r1]" "\n\t"
        "mov %[OUT], r2"
        : [OUT] "=r" (out)
        : [ARGV] "m" (argv)   //  <==== i don't know which constraint put here :/
        : "r0", "r1", "r2"
    );

    return out;
}

现在 GCC 抛出错误,我不知道如何解决它:

Assembler messages:
Error: invalid offset, value too big (0xFFFFFFFC)

谢谢

编辑:我已经用 Android NDK (arm-linux-androideabi-g++) 编译它

【问题讨论】:

  • 这对我使用 clang 进行了组装、链接和运行。不知道你怎么了。您确定是在这段代码中出错了吗?
  • 我忘了告诉我是用 Android NDK (arm-linux-androideabi-g++) 编译的
  • 如果你将argv的约束改为"rm",对你有用吗?
  • 是的,我还不能很简洁地回答这个问题,但我很确定这里有一个我们遗漏的微妙之处。一定很幸运,它对我有用。
  • 我尝试将 argv 指针转换为 int (int i_argv = (int)argv;) 并传递 i_argv 而不是 argv 并且它可以工作!但我不认为这是一个解决方案。这只是一个黑客:/

标签: c arrays gcc arm inline-assembly


【解决方案1】:

您不需要将 ARGV 或 OUT 移入/移出寄存器,这就是寄存器约束为您处理的事情。

"mov r1, #4\n\t"
"ldr %[OUT], [%[ARGV], r1]\n\t"
: [OUT] "=r" (out)
: [ARGV] "r" (argv)
: "r1"

注意:此代码在使用过高优化设置进行编译时确实会出现问题。 (我不知道如何解决,除了:使用 -O0 )

【讨论】:

    【解决方案2】:

    我认为它应该像这样工作:

    [ARGV] "r" (argv)
    

    意思是“将数组的地址加载到寄存器中”。

    【讨论】:

    • 是的,你是对的。我已经用MOV 替换了LDR 指令并使用r 约束,现在它工作正常。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多