【问题标题】:#define in inline assembly in GCC#define 在 GCC 的内联汇编中
【发布时间】:2018-09-26 20:30:32
【问题描述】:

我正在尝试在 GCC 中编写内联程序集,它将 #define 中的值写入寄存器。

#define SOME_VALUE  0xDEADBEEF

void foo(void)
{
    __asm__("lis r5, SOME_VALUE@ha");
    __asm__("ori r5, r5, SOME_VALUE@l");
}

但是,我在编译时遇到错误:

对“SOME_VALUE”的未定义引用

有没有办法让汇编器看到内联汇编中的#define

我通过以下方式解决了这个问题:

#define SOME_VALUE  0xDEADBEEF
__asm__(".equ SOME_VALUE,   0xDEADBEEF");

void foo(void)
{
    __asm__("lis r5, SOME_VALUE@ha");
    __asm__("ori r5, r5, SOME_VALUE@l");
}

但是,我真的不想重复这个值。

【问题讨论】:

  • 如您所见,__asm__ 将字符串作为参数。因此,请考虑对值/连接字符串进行宏字符串化。
  • 仅供参考,您的示例完全不安全。如果要破坏寄存器,则需要使用带有输出约束的扩展 asm。而且您绝对应该将多个指令放在同一个 asm 语句中;你不应该假设编译器会把你的 asm 语句背靠背。
  • 因此,如果您仍然使用扩展 asm,则可以使用约束来请求 SOME_VALUE 作为任何架构的立即数。或者只是要求编译器为您将其放入r5,并使用register int foo asm("r5") = SOME_VALUE;,然后将其用作输入。或者,如果您不关心什么寄存器,那么让编译器选择。
  • @PeterCordes 对,这只是一个愚蠢的例子。我意识到这是多么不安全。但是谢谢你指出来。以后有些人看书可能没有意识到。

标签: c assembly embedded inline


【解决方案1】:

在 C 中使用一些预处理器魔法来对值和字符串延续进行字符串化:

#define SOME_VALUE  0xDEADBEEF
#define STR(x) #x
#define XSTR(s) STR(s)

void foo(void)
{
    __asm__("lis r5, " XSTR(SOME_VALUE) "@ha");
    __asm__("ori r5, r5, " XSTR(SOME_VALUE) "@l");
}

XSTR 将扩展为字符串"0xDEADBEEF",它将与它周围的字符串连接起来。

这里是演示: https://godbolt.org/z/2tBfoD

【讨论】:

  • 是的,但这似乎是一个 XY 问题,因为内联 asm 会影响编译器的寄存器。请参阅我的问题;使用数字常量作为输入约束也可以作为立即数/文字或寄存器值。
猜你喜欢
  • 2012-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-23
  • 2011-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多