【问题标题】:How do I tell gcc that my inline assembly clobbers part of the stack?我如何告诉 gcc 我的内联汇编破坏了堆栈的一部分?
【发布时间】:2017-01-02 18:45:03
【问题描述】:

考虑这样的内联汇编:

uint64_t flags;
asm ("pushf\n\tpop %0" : "=rm"(flags) : : /* ??? */);

尽管可能有某种内在函数可以获取 RFLAGS 的内容,但我如何向编译器表明我的内联汇编破坏了堆栈顶部的一个四字内存?

【问题讨论】:

  • AFAIK,你不能。我认为写这个的唯一安全方法是在 pushf/pop 周围修改 rsp,这样你就不会踩到红色区域。 (使用 add -128 / sub -128 以便他们可以使用 imm8 编码)。然后当然输出约束必须是"=r",因为内存操作数可以使用rsp相对寻址模式。避免红区是任何人在讨论之前 SO 问题的同一问题时所能想到的最好方法。
  • 您也可以将[rsp-8] 保存/恢复到寄存器中,但这似乎比修改rsp 更糟糕,即使它会使堆栈引擎插入一个额外的uop。
  • 没有办法告诉扩展 asm 你正在破坏堆栈。也就是说,您到底想完成什么?可能还有其他一些技巧可以满足您的需求(也许是 lahf?)。
  • @DavidWohlferd 我正在考虑如何使用内联汇编来破坏堆栈的一部分,这是一个很好的激励示例,因为pushf 是获取整个 RFLAGS 寄存器的唯一方法。跨度>
  • 相关:你不能告诉 gcc 你想要破坏 整个 红色区域(除非使用 -mno-red-zone 编译整个文件或函数)。因此,要在 inline-asm 中进行函数调用,您必须跳过障碍:参见 stackoverflow.com/questions/37502841/…stackoverflow.com/questions/37639993/…。 (从内联 asm 调用函数只是一个坏主意,但是尝试使用 inline-asm 学习 asm 的人一直想要这样做。)

标签: c gcc x86-64 inline-assembly


【解决方案1】:

就我而言,目前这是不可能的。

【讨论】:

  • 一种解决方法是在使用堆栈之前执行add $-128, %rsp 之类的操作,跳过红色区域,然后使用sub $-128, %rsp。 (-128 适合 imm8,所以它小于 128 美元)。 TODO:链接现有的问答。
猜你喜欢
  • 2015-05-19
  • 1970-01-01
  • 2018-07-28
  • 2021-11-10
  • 2011-03-08
  • 2018-01-16
  • 2014-12-19
  • 2011-09-16
相关资源
最近更新 更多