2

我一直在阅读编译过程,我了解一些早期的概念,例如解析,但我不了解最后如何创建可执行文件。

在我在“编译器”周围看到的示例中,以 BNF 定义的语言形式接受输入,然后在解析它时输出程序集。

可执行文件真的只是二进制形式的程序集吗?我觉得这不可能是因为有应用程序可以从程序集中生成可执行文件?

如果这无法回答(即堆栈溢出格式太复杂),我会对链接/书籍完全满意,这样我就可以自学了。

4

3 回答 3

0

如果您想生成本机可执行文件,您有 2 个选项。您可以自己组装二进制形式,也可以将程序翻译成另一种语言并使用其编译器生成可执行文件

于 2014-10-12T11:15:28.923 回答
0

编译器(或更具体地说,链接器)创建可执行文件。

文件的格式通常因操作系统而异。

目前主要有两种格式ELF和COFF

http://en.wikipedia.org/wiki/Executable_and_Linkable_Format

http://en.wikipedia.org/wiki/COFF

如果你理解结构的概念,这也是一样的,只是在一个文件中。每个文件都有一个称为标题的第一个结构,您可以从那里根据需要访问其他结构。

在大多数情况下,只有生成的二进制代码保存在这些文件中,尽管您经常会找到调试信息。某些格式可以将源代码与代码一起保存,但现在它只保存对源代码的必要引用。

通过动态链接,您还可以找到包含实际符号名称的符号表。否则,只需要重定位表。

在 Amiga 下,我们还可以在“段”中定义代码。一次只能加载一个段。完成该段后,您可以将其卸载并加载另一个。然而,最终的概念是相似的。文件中的结构。

Microsoft 提供了有关 COFF 格式的 PDF。我刚才在他们的网站上找不到它,但看起来其他人有它。ELF 在 Wikipedia 页面中有许多链接,因此您应该能够找到 PDF 以开始使用。

于 2014-10-02T04:23:09.167 回答
0

除了一些(gcc 等)编译器之外,并非所有编译器都从高级语言转换为汇编语言,然后生成汇编器。汇编器读取汇编语言并生成机器代码并生成一个目标文件,正如您所猜测的那样,它不仅包含机器代码位。如果您考虑一下,您可能会意识到在另一个源文件中定义的变量或函数,这意味着它的代码存在于另一个目标文件中,直到链接时一个对象不知道如何获取该外部函数,所以 1)机器代码尚未完成,直到链接时间才完成外部地址的修补 2) 目标文件中需要一些信息来定义此目标文件中有哪些公共项目以及缺少哪些外部项目,例如,显然没有嵌入机器代码中的函数名称。因此,对象具有处于各种完成状态的机器代码以及链接器所需的其他数据。链接器然后......链接......将对象连接到一个程序中,一切都解决了,它基本上完成了所有机器代码并将机器代码的片段(在单独的对象中)放在一个地方。然后它必须以某种格式将所有内容保存在磁盘上,并且通常该格式不仅仅是原始机器代码。它在文件中有额外的东西,从头开始,以及定义每个二进制 blob 的方法以及在执行之前它需要在内存中的位置。当您在操作系统的命令行上运行程序或双击或在文件管理器 gui 中运行程序时,操作系统知道如何读取该文件格式,

aout、elf、coff、intel hex、motorola s-record 都是流行的格式以及一些工具链可以生成的原始二进制文件。gnu 工具将默认为一种(coff 或 elf 或 exe 或 aout),然后 objcopy 用于从一种转换为另一种或至少将默认一种转换为其他工具,并且有助于显示您可能的选择是什么。然后只需谷歌这些或维基百科他们并找到文件格式的定义。英特尔十六进制或摩托罗拉记录是从维基百科开始的好方法,然后是精灵。

于 2014-10-02T04:37:31.177 回答