【问题标题】:Equivalent for GCC's naked attribute等效于 GCC 的裸属性
【发布时间】:2012-01-12 13:14:58
【问题描述】:

我有一个用纯 C 编写的应用程序,其中混合了一些包含纯 ASM 的函数。裸属性不适用于 x86(为什么?为什么?!),并且我的 asm 函数不喜欢当序言和结尾弄乱堆栈时。是否有可能创建一个可以从 C 代码部分引用的纯汇编程序函数?我只需要这样的 ASM 函数的地址。

【问题讨论】:

  • 你可以做this。使用适合您的 OS 功能使内存区域可执行。

标签: gcc assembly x86 freebsd


【解决方案1】:

只需在功能块外使用asm()asm() 的参数被编译器简单地忽略并直接传递给汇编器。对于复杂的函数,单独的汇编源文件是避免笨拙语法的更好选择。

例子:

#include <stdio.h>

asm("_one:              \n\
        movl $1,%eax    \n\
        ret             \n\
");

int one();

int main() {
        printf("result: %d\n", one());
        return 0;
}

PS:确保您了解平台的调用约定。很多时候你不能只是复制/过去的汇编代码。

PPS:如果您关心性能,请改用extended asm。扩展 asm 本质上将汇编代码内联到您的 C/C++ 代码中,并且速度更快,尤其是对于短汇编函数。对于较大的汇编函数,最好使用单独的汇编源文件,因此对于极少数需要指向小型汇编函数的函数指针的情况,此答案确实是一个技巧。

【讨论】:

  • 这就是我要找的!谢谢你的解释。
  • asm() 外部功能块在c99 中似乎不起作用。
  • @hauzer 尝试使用__asm__asm__ 而不是asm
  • @hauzer 一个可移植的 c99 程序可能有一个名为 asm 的全局变量,它与这个 GCC 扩展冲突。但是以两个下划线开头的名称是为实现保留的(例如 GCC)。所以GCC扩展可以使用__asm__asm__仍然符合标准,但不符合asm
  • 我收到了错误 undefined reference to 'one' 并且不得不将声明更改为 int one() asm ("_one");(在 Linux 上)。
【解决方案2】:

大家好消息。 GCC 开发人员终于为 x86 实现了 attribute((naked))。该功能将在 GCC 8 中提供。

【讨论】:

  • 在一个有点相关的注释上。 GCC 7.1 通过 attribute((interrupts)) 以及相关的命令行选项 -mgeneral-regs-only 添加了对 x86 中断的支持。该实现还有一些不足之处,但它不再未实现。
【解决方案3】:

当然,只需创建一个.s 文件(汇编源),它通过gas(汇编器)运行以创建一个普通的目标文件。

【讨论】:

  • 如果您使用.S 后缀(大写S),您的汇编代码也将被cpp 预处理。
猜你喜欢
  • 2011-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-04
  • 1970-01-01
  • 2021-01-07
  • 1970-01-01
相关资源
最近更新 更多