使用GCC编译时,函数和变量前面是否会有&;_&;? [英] Will the functions and variables precede with an "_" when compiled using 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上出现的。
_
前缀,但我(主要)使用了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屋!