【发布时间】:2012-04-24 10:22:29
【问题描述】:
我正在 Xcode 4 上使用 gcc 编译器构建一些英特尔风格的内联汇编代码。 下面列出了部分内联汇编代码:
_asm
{
mov eax, esp
sub esp, 116
and esp, ~15
mov [esp+112], eax
}
在ship模式下,GCC将上述4行asm代码编译为:
mov %esp,%eax
sub $0x74,%esp
and $0xfffffff0,%esp
mov %eax,0x70(%esp)
这正是我想要的。 但是,在调试模式下,GCC 会将该代码编译为
mov %esp,%eax
mov %eax,%esp
mov %esp,%eax
mov %eax,-0x28(%ebp)
mov %esp,%eax
mov %eax,%esp
sub $0x74,%esp
mov %esp,%eax
mov %eax,-0x24(%ebp)
mov %esp,%eax
mov %eax,%esp
**and $0xfffffff0,%esp**
**mov %esp,%eax** **//changing the value of “eax”**
mov %eax,-0x24(%ebp)
mov %esp,%ecx
mov %ecx,%esp
**mov %eax,0x70(%esp)** **//store a “dirty” value to address 0x70(%esp), which is not we want**
解决上述问题的一种方法是使用 AT&T 样式指令重写内联 asm 代码,并将寄存器添加到破坏列表中。但是这种方式将是一项非常耗时的工作,因为要重写的代码太……太长了。
还有其他有效的方法来解决这个问题吗?让 gcc 编译器知道应该保留寄存器“eax”?
【问题讨论】:
-
倾斜代码使用寄存器 eax 来存储重要值,但 GCC 使用“eax”作为临时寄存器并“污染”寄存器“eax”。如何避免这种情况?
-
保存是什么意思?在 inline-asm 语句结束之后?这是没有意义的;一旦您的 asm 语句完成,编译器将再次拥有这些寄存器。如果您希望函数返回您在
eax中留下的内容,您需要使用 C 变量来实现。包含 asm 块的函数可以内联到另一个函数中...
标签: debugging gcc assembly xcode4 inline-assembly