compiler-construction - 程序中的标识符会发生什么?

标签 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;
}

我用了gcc - S sample.c我对汇编语言的输出感到惊讶。我丢失了所有变量名和函数名。

它保留了全局标识符,如人类、填充、主要,但它在它们前面加上下划线 _。因此,我不会将其视为使用标识符。无论如何,关键是它丢失了所有标识符。

我的问题是它如何调用函数或引用变量?

我真的很好奇输出的进一步阶段,这将是二进制的(这是不可见的)。

组装后和链接前的输出如何?我想它也会丢失下划线前缀的全局标识符吗?然后又一个问题是它如何调用函数或引用变量进行操作?

我在互联网上搜索了信息,但找不到任何有用的信息。可能是我不确定要搜索什么。我不想读这方面的大书。但是,如果有任何文章,教程,其中明确的概念。这也会有所帮助。

我是一个新手程序员。因此,如果您能用简单但技术性的术语进行解释,那就太好了。

编辑:作为回应,对评论。我把我的问题分解成多个问题。这是这个问题的第二部分:not clear with the job of the linker

最佳答案

在基 native 器级别,不再有名称,只有变量和代码的数字地址。因此,一旦您的代码被翻译成机器语言,这些名称就不再实用了。

如果您使用“to assembler”选项进行编译或反汇编代码,您可能会看到一些标识符;它们可以帮助您找到解决代码的方法,因为您不会不必要地在头脑中计算数据/代码偏移量。

要回答有关链接等的问题:一旦将程序编译为可重定位对象形式,仅在 C 程序文件“内部”使用的标签和标识符就会消失。但是,外部定义的名称,例如 main()需要,因为外部模块会引用它们;因此编译的目标文件将包含一个小表格,列出外部可见的名称以及它们所指的位置。然后,链接器可以根据这些名称将外部引用从其他人(反之亦然)修补到您的模块中。

链接后,即使是外部定义的名称也不再需要。但是,如果您使用调试选项进行编译,名称表可能仍会附加到最终程序,因此您可以在调试程序时使用这些名称。

关于compiler-construction - 程序中的标识符会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1986549/

相关文章:

parsing - 编程语言语法

c++ - 使用 GCC 程序集向左/向右旋转移动次数

assembly - 为什么具有对 _GLOBAL_OFFSET_TABLE_ 的非限定引用的 nasm 程序集显然可以作为 PIC 进行汇编和链接?

android - 使用 Android NDK 独立工具链时 PCRE 链接失败

ffmpeg - 链接主程序时,我的共享库中未定义的 FFMPEG 引用

c# - 子范围 & CS0136

c++ - X()、Y() 和 Z() 宏在 LLVM 中有什么作用?

c - Solaris cc 是否在可执行文件中嵌入了不同编译的不同信息?

c++ - 组装发送参数-fastcall

c++ - 如何在程序中包含数据对象文件(图像等)并访问符号?