【问题标题】:The using rules of %eax, %edx, %ecx in the same function frame%eax, %edx, %ecx 在同一个函数框架中的使用规则
【发布时间】:2020-07-14 09:28:04
【问题描述】:

环境:i386 32 位 组装:AT&T 操作系统:Linux

我只是想问一下%eax, %edx, %ecx寄存器在同一个函数框架中的使用顺序有什么规定吗?

据我观察,它们经常以%ecx、%edx 和%eax 的顺序出现在我的环境中,用于存储局部变量或其他临时变量。

谢谢大家。

【问题讨论】:

  • 没有这样的规则。但是,请记住,某些寄存器是 callee-saved 并且必须在退出函数时恢复到它们的原始值。在 i386 Linux 上,这些是 rbx、rsi、rdi、rsp 和 rbp;浮点堆栈也必须为空(除非您返回一个浮点数)。
  • 知道了,谢谢。
  • 参考 i386 SysV ABI 以进一步阅读。该文档指定了为 Linux 编写 i386 汇编函数时需要遵守的所有规则。
  • @fuz 你的意思是ebx、esi、edi、esp 和rbp?我认为 80386 上没有 64 位寄存器。
  • @fcdt 你的意思是ebp?我认为 80386 上没有 64 位寄存器。;-)

标签: assembly x86 calling-convention att i386


【解决方案1】:

如 cmets 中所述,与 i386 System V ABI 有关(更多链接在 x86 tag wiki):

eax、ecx 和 edx 是暂存寄存器,它们不必在函数调用之间保留。所有其他 32 位通用寄存器都必须保存在堆栈中,这需要额外的指令。

因此,最好在同一个函数中首先使用eax、ecx和edx,然后再使用ebx、esi、edi、esp和ebp。

(为了便于阅读,这里省略了百分号)

【讨论】:

  • Re:省略% 符号:寄存器名称不包含%。 AT&T 语法在 reg 名称上使用 % 装饰以避免寄存器名称和符号名称之间的歧义,但这并不意味着装饰是正确的寄存器名称的一部分。例如在 GNU C 内联汇编中,clobber 列表可以只使用 "eax"(或者 GCC 也接受 "%eax"。)
  • 感谢您的来信。它们包含在 ABI 文档中,所以我假设(通常我只使用 intel 语法)。
  • 这几乎是What registers must be preserved by an x86 function? 的副本,但我想明确指出使用调用破坏寄存器可以节省保存/恢复的工作是答案的真正症结,所以+1。 (有趣的事实:所有主流的 32 位 x86 函数调用约定都同意 EAX、ECX 和 EDX 被调用破坏,其余的被调用保留。)
猜你喜欢
  • 2017-03-29
  • 2013-07-23
  • 1970-01-01
  • 2015-01-03
  • 2016-02-09
  • 1970-01-01
  • 2018-08-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多