【发布时间】:2016-09-07 12:35:51
【问题描述】:
我正在使用 gcc 的扩展 asm 来调用系统调用。我正在 PowerPC (Freescale MPC5200B) 上开发专有的 RTOS。
根据 gcc 的documentation,我应该将汇编代码使用的所有寄存器(既不是输入也不是输出)添加到 clobbers 列表中,因为 gcc 不分析汇编代码,因此不知道哪些寄存器正在改变了。
问题是我不知道系统调用改变了哪些寄存器。事实上,我正在观察系统调用更改持有指针的寄存器的情况。系统调用返回后,寄存器中的指针正在被使用,导致内存访问无效。
我应该如何处理这种情况?
【问题讨论】:
-
系统调用指令本身会修改 RCX 和 R11 :felixcloutier.com/x86/SYSCALL.html。然而,Linux 也会根据操作结果更改 RAX。后一个寄存器记录在 A.2.1 调用约定部分的System V 64-Bit ABI 中,其中指出:2。系统调用是通过 syscall 指令完成的。内核销毁寄存器 %rcx 和 %r11。
-
还有5。从系统调用返回,寄存器 %rax 包含系统调用的结果。介于 -4095 和 -1 之间的值表示错误,即 -errno。
-
我应该如何处理这种情况? 在 rcx 和 r11 上声明 clobbers,并使用
"=a"(retval)以便 gcc 知道结果在 rax 中。顺便说一句,x86 tag wiki 有很多好东西的链接,包括 dup-target ,其中包含对系统调用破坏哪些 regs 的问题的答案。 (我并不是说您应该自己找到它;这是在您还不知道的情况下很难找到正确搜索词的情况之一。) -
我既不在 Linux 也不在 x86 上。我正在 PowerPC 上开发专有的 RTOS。但我认为你们的 cmets 为我指明了正确的方向。
-
未来读者:作为stackoverflow.com/questions/2535989/… 的副本暂时关闭,这解释了在 x86-64 和 x86-32 System V ABI 中跨系统调用保留哪些寄存器(即:几乎所有他们)。我同意@MichaelPetch 的观点,这不再是一个骗局。不过,在澄清它是什么操作系统和架构之前,这个问题应该被关闭!
标签: gcc assembly inline-assembly powerpc