Ali*_*ice 6 compiler-construction assembly linker
我是新手程序员.我只想看到不同阶段的输出编译,汇编和链接.我也不懂汇编语言.
我写了一个简单的程序
#include <stdio.h>
int humans = 9;
int main()
{
int lions = 2;
int cubs = populate(lions);
return 0;
}
int populate(int crappyVariable)
{
return ++crappyVariable;
}
Run Code Online (Sandbox Code Playgroud)
我使用gcc - S sample.c汇编语言的输出感到惊讶.我丢失了所有变量名称和函数名称.
它保留了像人类,填充,主要的全局标识符,但它以下划线_为前缀.所以,我不认为它使用标识符.无论如何,重点是丢失了所有标识符.
我的问题是它如何调用函数或引用变量?
我对输出的更多阶段感到好奇,这些阶段将是二进制的(这是不可见的).
如何在组装之后和链接之前输出?我猜它甚至会松散下划线前缀全局标识符?那么问题是如何调用函数或引用变量进行操作?
我在互联网上搜索信息,但找不到任何有用的东西.可能我不知道该搜索什么.我不想读这本书的大书.但是如果有任何文章,教程清楚概念.这也会有所帮助.
我是新手程序员.所以,你可以用简单但技术性的术语来解释它.
编辑:作为回应,评论.我把问题分成了几个问题.这是这个问题的第二部分:不清楚链接器的工作
在基本的机器级别,不再有名称,只有变量和代码的数字地址。因此,一旦您的代码被翻译为机器语言,这些名称就不再适用于实际用途。
如果您使用“到汇编器”选项进行编译或反汇编代码,您可能会看到一些标识符;它们可以帮助您找到解决代码的方法,因为您不需要在头脑中计算不必要的数据/代码偏移量。
回答有关链接等的问题:一旦程序被编译为可重定位对象形式,仅在 C 程序文件“内部”使用的标签和标识符就会消失。但是,main()需要外部定义的名称,例如,因为外部模块将引用它们;因此,编译后的目标文件将包含一个小表,列出外部可见的名称以及它们引用的位置。然后,链接器可以根据这些名称将来自其他模块的外部引用拼凑到您的模块中(反之亦然)。
链接后,甚至不再需要外部定义的名称。如果您使用调试选项进行编译,名称表可能仍会附加到最终程序中,因此您可以在调试程序时使用这些名称。