我一直在读到,在大多数情况下(如 gcc),编译器以高级语言读取源代码并吐出相应的机器代码。现在,机器代码的定义是处理器可以直接理解的代码。因此,机器代码应该仅依赖于机器(处理器)且独立于操作系统。但这种情况并非如此。即使 2 个不同的操作系统在同一处理器上运行,我也无法在这两个操作系统上运行相同的编译文件(对于 Windows 为 .exe,对于 Linux 为 .out)。
那么,我错过了什么? gcc 编译器(和大多数编译器)的输出不是机器代码吗?或者机器代码不是最低级别的代码,操作系统将其进一步转换为处理器可以执行的一组指令?
你混淆了一些事情。我的可重定向编译器(如 gcc 和其他通用编译器)将文件编译为对象,然后链接器稍后根据需要将对象与其他库链接起来,以生成所谓的二进制文件,然后操作系统可以读取、解析、加载可加载块并开始执行。
理智的编译器作者将使用汇编语言作为编译器的输出,然后编译器或用户在其 makefile 中调用创建对象的汇编器。这就是 gcc 的工作原理。以及 clang 的工作方式,但 llc 现在可以直接制作对象,而不仅仅是组装的组件。
生成可生成原始机器代码的可调试汇编语言更有意义。您确实需要一个像 JIT 这样的充分理由来跳过这一步。我会避免直接进入机器代码的工具链,因为它们可以,但它们更难维护,并且更有可能出现错误或需要更长的时间来修复错误。
如果架构相同,那么您就没有理由不能使用通用工具链为不兼容的操作系统生成代码。例如,gnu 工具就可以做到这一点。操作系统差异不是在机器代码级别定义的,大多数是在高级语言级别的 C 库,您可以创建 GUI 窗口等,与机器代码或处理器架构无关,对于某些操作系统来说是相同的操作系统特定的 C 代码可以在 mips、arm、powerpc 或 x86 上使用。架构变得具体的是调用实际系统调用的机制。经常使用特定的指令。机器代码最终会被使用,但没有理由不能在实际或内联汇编中进行编码。
然后这导致库,甚至 fopen 和 printf 这些通用 C 调用最终也必须进行系统调用,因此库支持代码可以采用跨系统兼容的高级语言,因此需要一个系统和架构最后一英里的特定代码。您应该在 glibc 源代码中看到这一点,或者在其他库解决方案中挂钩到 newlib 中。作为例子。
对于 C++ 等其他语言也是如此。解释型语言具有额外的层,但它们的虚拟机只是位于相似层上的程序。
低级编程并不意味着机器语言或汇编语言,它只是意味着您使用的任何编程语言都可以在较低级别进行访问,例如应用程序下方或操作系统下方等......
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)