GCC 内联汇编:仅具有内联汇编代码的函数体

lll*_*lll 3 c x86 gcc inline-assembly

我正在尝试在我的 C 项目中重用一些汇编代码。假设我有一系列指令,并且我想将它们组织为一个函数:

void foo() {
  __asm__ (
   "mov %eax, %ebx"
   "push %eax"
   ...
   );
}
Run Code Online (Sandbox Code Playgroud)

然而,一个障碍是,在 function 编译后的汇编代码中foo,除了内联汇编代码之外,编译器还会为该函数生成一些序言指令,整个汇编程序将变成这样:

foo:
   push %ebp          <---- routine code generated by compilers
   mov  %ebp, %esp    <---- routine code generated by compilers
   mov %eax, %ebx
   push %eax
Run Code Online (Sandbox Code Playgroud)

考虑到我的使用场景,这样的例程代码实际上破坏了内联程序集的原始语义。

所以这是我的问题,有什么方法可以阻止编译器生成这些函数序言和结尾指令,并且只包含内联汇编代码?

Aja*_*iya 5

你提到你使用 gcc 进行编译。在这种情况下,您可以使用-O2优化级别。这将导致编译器进行堆栈优化,如果您的内联汇编很简单,它不会插入序言和尾声。不过,这可能无法在所有情况下得到保证,因为优化不断变化。(我的 gcc-O2可以做到这一点)。

另一种选择是您可以将整个函数(包括 )foo:放入汇编块中,如下所示

__asm__ (
    "foo:\n"
    "mov ..."
);
Run Code Online (Sandbox Code Playgroud)

使用此选项,您需要知道名称修改规范(如果有)。.globl foo如果您希望函数是非静态的,您还必须在函数启动之前添加。

__attribute__ ((naked))最后,您可以检查函数声明中的gcc属性。但正如MichaelPetch提到的,这不适用于 X86 目标。

  • _GCC_ 中的 `__attribute__((naked))` 不适用于 x86 目标。虽然这个问题没有用x86标记,但显示的代码是x86。您应该在当前版本的 _GCC_ 上收到“警告:‘裸’属性指令被忽略”警告 (5认同)