0

我在这篇文章中积累了三个不同但背景相似的问题。以下相同。

  1. 从源 -> 可执行的步骤序列
  2. 32/64 位版本的编译器
  3. c 数据类型大小对编译器的依赖性

Q1:从源代码->可执行的步骤顺序

我认为以下是从源文件生成可执行文件的步骤

  • 编写的源文件是用任何高级/中级语言编写的,并由编译器进行预处理。
  • 当我们使用GCC/G++时,gcc -save-temps -c同时生成一个.S 和一个 .O文件,它们分别是程序集(可读)和目标代码(非人类可读)。
  • 最后阶段是这个目标代码被链接以解析未知符号以创建机器(或)可执行代码。

所以这里的问题是这些假设对吗?我经常看到术语对象和机器代码可以互换使用。两者之间的确切区别是什么。?

Q2:32/64 位版本的编译器

在 Q1 的上述步骤中,编译器类型的影响究竟在哪里。是不是生成的汇编代码被改变了?

Q3:c 数据类型大小对编译器的依赖性

就 c 编程而言,数据类型的大小取决于编译器类型(或)硬件类型。请详细说明这些因素的依赖关系。尽管我在堆栈溢出中看到了与 Q3 的一些讨论,但我仍然对此感到困惑。

4

1 回答 1

2

第一季度

这是正确的,但可能没有组装阶段。而“预处理”是一个很好的小词,含义丰富。

对象代码和机器代码通常几乎相同。目标代码可能包含机器代码或一些可解释的代码,非机器代码。目标代码通常不是执行的最终代码,需要链接器进一步处理。包含机器代码的可执行文件通常需要一些类似于链接器的处理,但这部分是由操作系统完成的。希望可执行文件可重定位,也就是说,能够将它们加载到内存中的任何位置以在那里运行它们。重定位涉及在加载之后但在执行之前修复可执行文件内部的地址。在运行时链接到 DLL 是操作系统执行的另一个类似链接器的功能。

第二季度

“预处理”是开始出现类型及其大小的第一步。编译器必须执行类型检查、类型转换和代码/数据生成。在所有这些步骤中,类型都不容忽视。0xFFFF 是一个int还是一个unsigned int?编译器应该为指针保留多少内存?应该为 100 的数组分配多少空间doubles?编译器究竟是如何提升charsints?代码优化呢?所有这些问题的答案都需要知道字体大小。当然,生成的程序集或机器代码将取决于它们。

第三季度

理论上,类型大小取决于编译器。在实践中,为了避免模拟目标硬件不直接支持的类型的不必要开销,您拥有的类型直接对应于硬件支持的类型。C 在其起源和本质上几乎是一个可移植的汇编程序,这应该可以解释它的许多“奇怪之处”(太原始,让你很容易自爆,有许多未定义和特定于实现的行为,等等)。

于 2012-09-26T10:34:51.757 回答