了解不同平台编译器的需求

Bar*_*uch 5 compiler-construction operating-system

我试图了解整个构建链是如何工作的,这样我就可以更好地理解构建/链接/编译等时发生的事情.

我遇到麻烦的一点是:如果编译器将源转换为本机程序集,为什么不能在不同的OS上运行相同的程序?是不是直接由CPU运行程序集?所以相同的机器代码应该在每个操作系统上运行,只要它是相同的架构,不是吗?为什么不?

编辑:到目前为止,大多数答案都是关于调用操作系统的API.这显然是个问题.我的问题是关于直机器代码.是否直接传递给CPU?如果我在汇编中编写了一个程序,我还需要为每个操作系统单独编译吗?(侧点:如果我使用标准的c ++ cin/cout,是否依赖于操作系统,编译为直接汇编I/O,或答案取决于编译器?)

Mic*_*yan 8

不同的操作系统支持不同的二进制格式(例如ELF与COFF),不同的动态链接器(在分发二进制文件后,*.so,*.dll和*.dylib文件在运行时链接),并提供不同的集合用于使用OS提供的功能的函数和库.

可以通过例如Single UNIX Specification/IEEE Std来解决不同的功能集.1003.1(POSIX),它规定了在所有操作系统中为各种操作系统任务提供的一组功能(遗憾的是并非所有操作系统 - 嗯,Windows - 遵守).关于二进制格式(以及CPU指令集架构),解决这个问题的一种方法是分发一些更高级别的二进制格式(字节码),然后对目标指令集进行即时转换.二进制格式(虽然这更多的是关于改变时...它仍然需要完成).例如,低级虚拟机(LLVM)提供这种转换.


Aar*_*otz 8

它归结为操作系统的APIABI.

不同的操作系统提供不同的系统调用,以及调用这些系统调用的不同机制.例如,虽然POSIX提供forkexecv创建了一个新进程,但Windows提供了CreateProcess.

此外,在装配层面也存在差异.你用什么汇编代码来调用函数?不同的操作系统预期不同的调用约定.操作系统也不一定就可执行二进制文件的格式达成一致,也不同意其他机制,如动态链接.

另一个要考虑的问题是并发性以及操作系统如何处理这种情况.某些操作系统在内核级别识别线程,而其他操作系统则不识别.有些人可能只是喜欢使用多个进程,有些人可能会使用完全不同的模型.API不同,抽象可能不同.例如,一个操作系统可能使用锁和信号量,另一个可能使用消息传递.


pax*_*blo 6

因为,一方面,与操作系统接口的能力在平台之间不一致.即使Linux的/ 86,Windows和Mac /英特尔(可全部使用相同的CPU)之间,做事情的方式可能千差万别.

所以,当一个编译器可能会产生一定的作用,你的对象链接到特定于平台的库微小物体的文件,他们成为天生不可移植.

一个例子是内存分配.如果要在UNIX下从OS请求更多内存,可以使用brksbrk库函数.这不是 C标准库的一部分,更像是UNIX特定的库.

另一方面,Windows可能提供Win32GetMem执行相同操作的功能.