【问题标题】:PowerPC Inline Assembly: Load C Value into RegisterPowerPC 内联汇编:将 C 值加载到寄存器中
【发布时间】:2017-10-14 22:00:58
【问题描述】:

使用GCCinline assembly,我想将立即数加载到特定寄存器r0。但是,我没有得到正确的结果。

unsigned short value = 0x1337;

asm volatile
(
"li 0, %0\n\t"
        "sc\n\t"
        "blr"
: /* Output registers */
:"r"(value) /* Input registers */
: /* No clobbered registers */
);

编译后会给出

li        r0, 9
sc
blr

9 来自哪里?我想要指定的值0x1337Here是我看的教程。

【问题讨论】:

    标签: c gcc assembly inline-assembly powerpc


    【解决方案1】:

    9 是包含0x1337 的寄存器,这正是您所要求的。注意value 是一个输入寄存器吗? 9,又名 r9,是一个完全有效的输入寄存器。这是我得到的汇编输出。

        li 9,4919
        li 0, 9
        sc
        blr
    

    如果您想立即加载 0x1337,只需使用它即可。

    asm volatile (
        "li 0, 0x1337\n\t"
        "sc\n\t"
        "blr"
    );
    

    或者,只使用"i" 约束而不是"r" 约束。

    asm volatile (
        "li 0, %0\n\t"
        "sc\n\t"
        "blr"
        :
        : "i"(0x1337)
    );
    

    【讨论】:

    • 是的,不出所料,这是一个简单的解决方案
    • @BullyWiiPlaza:使用gcc -mregnames 获取不是裸数字的寄存器名称,因此您不能混淆寄存器和立即数。另外,请确保告诉编译器您破坏的任何寄存器,并使用asm goto 告诉它您正在跳转。虽然我不确定是否有一种安全的方法可以告诉编译器您的 asm 需要 lr 中的返回地址并返回。您可能应该在 asm 中编写整个函数,因为如果它内联,我看不出它是如何工作的。
    • @PeterCordes:是的,这就是全部功能。 :)
    • @BullyWiiPlaza:那么您应该在内联 asm 中放置一个标签,并将 asm 语句放在全局范围内,而不是放在 C 函数中。否则,您需要阻止该 C 函数与 __attribute__((noinline)) 内联,这违背了内联汇编的目的。
    • @PeterCordes:上次我检查时,您仍然可以将寄存器和立即数与-mregnames 混淆,因为寄存器名称只是汇编宏。不过,当人类阅读代码时,它确实会更加明显。
    猜你喜欢
    • 1970-01-01
    • 2015-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-21
    • 2014-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多