我正在 Xcode 4 上使用 gcc 编译器构建一些 intel 风格的内联汇编代码。下面列出了部分内联汇编代码:
_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”?