【问题标题】:Compilation error with %hi() and %lo() with inline assembly code带有内联汇编代码的 %hi() 和 %lo() 编译错误
【发布时间】:2015-05-14 13:02:52
【问题描述】:

我有以下内联汇编代码。我在存在 %hi、%lo 的每一行都收到编译错误“错误:无效的 'asm':在 %-letter 后缺少操作数编号”。

void func()
{

  __asm__ (
  "lis %%r4, %hi(%0);"
  "ori %%r4,%%r4,%lo(%0);"
  "stw r3, 0(%%r4);"
  "lis %%r4, %hi(%0);"
  "ori %%r4,%%r4,%lo(%0);"
  "lis %%r3, %hi(%1);"
  "ori %%r3,%%r3,%lo(%1);"
  "stw %%r3, 0(%%r4);"
  ::"r"(var1), "r"(var2));
}

经过进一步分析,我发现内联汇编在找到 % 符号时需要一个数字(%0, %1...)。所以将所有 % 更改为 %%(这只是一个盲注),然后最终得到了许多如下所示的。

{standard input}: Assembler messages:
{standard input}:3394: Error: bad expression
{standard input}:3394: Error: syntax error; found `h', expected `,'
{standard input}:3394: Error: junk at end of line: `hi(%r9)'
{standard input}:3394: Error: bad expression
{standard input}:3394: Error: syntax error; found `l', expected `,'
{standard input}:3394: Error: junk at end of line: `lo(%r9)'
{standard input}:3394: Error: bad expression

经过大量努力,我知道如果我们在内联汇编代码中使用 %hi() 或 %lo 会出现一些问题。如果我从我的代码中删除 %hi 和 %lo ,它就会被编译。谁能建议我如何在内联汇编代码中使用 %hi() 和 %lo ?

【问题讨论】:

  • 糟糕,我看到您尝试将 % 符号加倍。然后查看生成的 asm 代码,使用 gcc -S。 PS:您的代码至少缺少clobber列表。
  • @Jester 这只是一次盲目的尝试。我想做的就是在我的汇编代码中使用 %hi() 和 %lo 。我认为clobber list是可选参数,所以我没有使用它。
  • 无论如何你都应该使用它。这是有充分理由的。想想编译器在优化时内联的函数。

标签: c gcc assembly


【解决方案1】:

GNU AS 不支持%hi()%lo()。相反,它在符号上使用@h@l 后缀来表示高位和低位部分。另请注意,您不能将其与寄存器操作数一起使用,并且您使用了r 约束。

【讨论】:

  • 我已经尝试过该选项并得到以下错误{标准输入}:汇编程序消息:{标准输入}:3394:错误:语法错误;找到@', expected ,'{标准输入}:3394:错误:行尾有垃圾:`@h'。您还可以详细说明您在代码中提到的寄存器操作数。
  • 您使用了r 约束,因此编译器将您的输入放入寄存器,但您不能将@h/l 与寄存器一起使用,就像您也不能使用%hi/lo 一样。如果你使用寄存器,编译器已经加载了完整的地址,所以你不需要自己弄乱lis/ori
  • 那如何提供输入呢?
  • 尝试改用m
  • “u”是什么意思,我只是在一些文档中看到并使用它,它有效。你知道吗?
猜你喜欢
  • 1970-01-01
  • 2023-03-25
  • 2015-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多