7

回答者已经知道的东西,但无论如何这里展示我的思考过程:

从 HLL 到机器代码,这里有一组粗略的事件发生(有链接器和其他东西,但现在让我们忽略它):

HLL --> 编译器 --> 汇编器 ----> 机器码

根据我购买的硬件,它可能有不同的处理器(英特尔、SPARC、ARM 等)。汇编语言是特定于处理器的。因此,当代码来自编译器 --> 汇编器时,生成的汇编代码是特定于处理器的。

言归正传:

例如:我的硬件上有 Windows 操作系统。我得到了“Windows 7 64 位的 C 编译器”。而且我在相同的硬件上也有 Ubuntu,并且我得到了“适用于 Ubuntu 64 位的 C 编译器”。

  1. 我可以在具有不同处理器架构的不同硬件上拥有相同的操作系统,或者在同一硬件上拥有不同的操作系统(如上面的示例)。当我下载 C 编译器时,为什么编译器被列为特定于操作系统的?而不是特定于处理器?由于编译器的重点是将 HLL 转换为汇编,这是特定于处理器架构而不是特定于操作系统的。

  2. 假设 1. 是如何完成的,当我下载适用于 Windows 7 和 Ubuntu 的编译器时,编译器如何知道要生成什么处理器特定的汇编代码?编译器是否带有各种特定于处理器的汇编器?

4

2 回答 2

5

有几个因素在其中起作用。对于台式机,实际上只有两种架构在使用:32 位是 x86(带有各种扩展),64 位是 x86-64。所以很多软件可以忽略这个问题,只指定“位”。对于 Windows RT/8 之前的 Windows 尤其如此,它甚至不尝试支持任何其他体系结构。

虽然编译器必须了解处理器架构,但几乎所有有趣的程序都必须以一种或另一种方式与操作系统交互。即使您的代码不与操作系统交互,编译器也必须知道二进制文件使用哪种文件格式、链接哪些库等等。运行时库也是特定于操作系统的,并且通常与编译器捆绑在一起。

至于编译器如何知道要生成什么样的指令:您下载的二进制文件是专门为一种架构量身定制的(无论您从中获得它的页面是否提到过)并且无法为其他架构生成代码,或者它确实有几个后端编译。

也就是说,我没有看到很多编译器声明为“ <language>compiler for <operating system>”。编译器编写者通常在指定指令集方面更加迂腐,分发者也是如此。只有 Windows 的人对此非常草率,因为直到大约一年前它还不是有用的信息。

于 2013-09-21T17:46:47.233 回答
0

对于实际计算,比如添加两个数字,只有硬件很重要,在 Windows 和 Linux 下你确实会得到相同的机器代码。

有趣的“胶水”由平台库提供,例如标准 C 库,它提供了“在标准输出上打印字符”的功能。函数调用代码也完全由硬件决定(尽管 Windows 和 Linux 之间有一些约定不同,例如函数参数的放置位置,但这些只是约定)。这些库的实现提供了有趣的特定于平台的“肉” 。例如,如何printf 实施?Linux 和 Windows 上生成的代码不同,但不同之处不在于指令的种类,而在于您与操作系统的对话方式。

同样,这主要是一个约定问题,对于同一硬件上的不同操作系统,程序的实际机器代码没有太大差异。不同之处仅在于您如何让操作系统代表您执行某些操作,例如输入/输出、给您内存、告诉您时间等。

于 2013-09-21T18:11:03.117 回答