我正在学习C而我并不了解哪些因素决定了所需的编译器及其原因。
让我们说我的C代码是一个小型控制台应用程序,我想为特定平台编译它。该平台将具有特定的操作系统和指令集。
指令集如何影响需要哪个编译器?它取决于实际指令集还是仅取决于其寄存器大小(16/32/64位)?如果它只取决于它是64位还是32位,那么指令集看起来是不同的,那么机器码就不起作用了?我对此感到困惑,因为即使有几种可能的指令集,也会提供32位和64位版本的应用程序。
在特定指令集之上运行的OS是否会影响需要哪个编译器以及为什么?如果CPU相同,那么机器代码是否相同?
更新
感谢所有人的回答。 我的final conclusion
答案 0 :(得分:3)
指令集如何影响需要哪个编译器?
如果处理器具有不同的指令集,则编译器需要产生不同的指令。大多数编译器都支持多个指令集,因此您可能不需要仅仅因为指令集发生更改而更改编译器。
是否取决于实际指令集或仅取决于其寄存器大小(16/32/64位)?
两个
如果它仅取决于它是64位还是32位,那么指令集看起来是不同的,那么机器代码就不起作用了?我对此感到困惑,因为即使有几种可能的指令集,也会提供32位和64位版本的应用程序。
虽然有不同的指令集x86和x64在桌面市场占据主导地位,大多数软件供应商都认为不需要支持任何其他指令。
在特定指令集之上运行的OS是否会影响需要哪个编译器以及为什么?如果CPU相同,那么机器代码是否相同?
指令集相同但与操作系统通信的方式不同。原则上,如果它们都在同一个指令集上运行,你可以在linux上运行一个windows应用程序,但是,应用程序会说" windows打开那个文件"和Linux不知道该怎么做。 wine项目填补了空白,并通过翻译" windows打开该文件来运行Linux下的Windows应用程序。到" linux打开那个文件"如果需要实现更多特定于Windows的功能,这会变得复杂。
答案 1 :(得分:2)
这绝对取决于程序运行的机器。不仅在8/16/32/64寄存器上,而且(更重要的是)在指令集本身上。如果你尝试在32位ARM处理器上运行32位x86程序,当然它不会工作。这仅仅是因为机器代码在每个架构上都非常具体,因此定义了哪个位做什么/意味着什么。即使一些指令的长度可能相同,操作数排序可能不同,或者某些位可能具有不同的含义,或者(很可能)操作码本身可能完全不同。因此,x86上的MOV
在不同的架构上也可能与BLOWUPTHEWORLD
具有相同的操作代码。这就是为什么每个架构都有特定的编译器。嵌入式系统(从平面控制器到RaspberryPis,再到控制玩具车的AVR),几乎可以为每个处理器/微控制器系列提供不同的编译器。
您在大多数应用程序中看到的除32位和64位之外的差异在某种程度上受到操作系统的屏蔽,因为操作系统的一个作业是提供抽象(想想系统调用,例如open
文件)无论底层是什么意思(从低级指令的角度来看)。 32甚至64位是一个差异,即使操作系统可能无法隐藏。
是。想想动态库。微软的DLL肯定无法在Linux上运行,除非有些人手动解码它们。 Linux上的Viceversa,共享对象(.so)不能仅仅因为它们以完全不同的方式构建而在Windows上运行。
答案 2 :(得分:1)
您提到的所有因素对您选择的编译器都很重要。指令集,ABI包括寄存器大小,您尝试部署到的操作系统以及要运行编译器的操作系统。您可以在同一台计算机上运行不同的操作系统(例如,购买iMac,您可以安装MacOS,多种Linux,几种Unix或Windows),因此单独的CPU不足以决定您需要哪种编译器。有时您可以使用相同的编译器,只需要一组不同的头文件即可访问操作系统的功能。
但是,这并不能保证选择特定的编译器。编译器本质上只是一个应用程序。将文本转换为机器代码的转换器。因此,有许多编译器可以在几个平台上运行(即ABI,OS和CPU的组合),以及许多可以为多个平台生成可执行文件的编译器。对于一些较小的CPU和操作系统(例如嵌入式CPU),OTOH有时只有一个编译器。