使用GCC编译时,函数和变量前面是否会有&_&? [英] Will the functions and variables precede with an "_" when compiled using gcc?

查看:30
本文介绍了使用GCC编译时,函数和变量前面是否会有&_&?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习使用GCC在linux环境下开发操作系统。我从Bran的内核开发中了解到,在编译C中的所有函数和变量名时,其相应的汇编源文件中的前面都有一个"_"(下划线)。 但是当我翻阅编译后的C程序的汇编源程序时,我甚至找不到"_main"函数。 我执行了以下操作。

cpp sample.c sample.i

GCC-S样本I.

推荐答案

早期确实如此。给定的C函数foo将在汇编程序中显示为_foo。这样做是为了避免与手动生成的.s文件冲突。

还将限制为总共8个字符[链接器限制]。

几十年来这都不是真的。现在,符号不再以_为前缀,并且长度可以远远超过8个字符。


更新:

那么现在GCC不在函数和变量前面产生a_了吗?

在很大程度上,不是。国际海事组织,在这一点上,您引用的参考资料似乎确实有点过时。

大多数POSIX系统(例如Linux、*BSD)使用gcc[或clang],并且省略了_

当我第一次开始用C(大约1981年)编程时,_仍然在使用。这是在AT&;T Unix v7、System III和System V上出现的。

IIRC,对于较新的系统(如Linux),它在20世纪90年代初就消失了。就我个人而言,从那以后我再也没有遇到过_前缀,但我(主要)使用了Linux[有时也使用了cygwin]。

一些AT&;T Unix派生的系统可能为了向后兼容而保留了它,但最终,大多数人都标准化了"foo is foo"。我无法访问OSX,因此不能排除乔纳森对此的评论。

_从Unix的早期(大约1970年)就已经出现了。那是在我之前,但是,IIRC,Unix最初是用汇编语言编写的。它已转换为C。_用于划分用C编写的函数或可以从C函数调用的ASM函数。

那些没有前缀的是"仅限ASM"[因为它们可能使用了非标准的调用约定]。回到过去,一切都很珍贵:RAM、CPU周期等。

因此,ASM函数可以/将使用"技巧"来节约资源。多个ASM功能可以作为一个组工作,因为它们相互了解。

如果可以从C调用给定的ASM函数,则_前缀符号是其与C兼容的"包装器"[它在序言/结尾中执行额外的保存/还原]。

所以,我只能调用C程序的main函数作为"call main",而不是"call_main"?

这是一个相当安全的赌注。

如果您从C调用给定的函数,它将自动执行正确的操作(即是否添加前缀)。

只有在尝试从手动生成的汇编程序中调用C函数时,才可能出现问题

因此,对于ASM,我只需要做简单的事情,然后做call main。它可以在大多数(如果不是全部)系统上运行。

如果您希望代码"防弹",可以通过C预处理器(通过.S文件)运行ASM,然后执行(例如):

#ifdef C_USES_UNDERSCORE
#define CF(_x)          _##_x
#else
#define CF(_x)          _x
#endif

    call    CF(main)

但是,我认为这是矫枉过正。

还说明了_前缀的整个问题。在[具有大量内存和CPU周期]的现代系统上,为什么汇编程序函数必须知道它调用的ABI兼容函数是从C还是手写汇编程序生成的?

这篇关于使用GCC编译时,函数和变量前面是否会有&_&?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆