在windows中,当我编译一个简单的'C'程序时,我得到了最终的可执行机器代码.exe
。
在unix中使用gcc的同样的事情产生一个.out
机器代码文件。
这些之间有什么区别?
我的基本问题是,.exe
和.out
是机器代码,为什么它们依赖于操作系统?
在Unix中,我无法直接执行.exe
,在Windows中,我无法执行Unix的.out
。为什么会这样?
答案 0 :(得分:12)
这一切都与程序的加载方式有关。
Windows和Linux对于程序自定义的方式有不同的格式。
在Linux中,通常使用ELF格式。对于Windows,它是PE。
这些格式定义了执行机器指令所需的程序的不同数据。
此外,操作系统接口不同,因此需要使用不同的库,并且需要进行不同的系统调用。
对于一个简单的程序,您通常可以在其他操作系统上重新编译,使其同时工作,但您将无法在这两个文件上使用单个文件。
答案 1 :(得分:1)
操作系统抽象出对底层硬件的访问,并通过系统调用使其可供程序员使用。在Windows中,这些是通过Windows API完成的(通常通过使编程更容易的库进一步抽象,如MFC等)。在UNIX中,这通常通过中断来完成,系统的C库通过遵循POSIX api(通常具有一些依赖于系统的添加)来使其更容易一些。
例如,在Linux上,系统调用是通过int 0x80
进行的,有几个寄存器加载了函数的参数,而C库允许你调用,例如, read
,带有预期参数( int fd, void *buf, size_t count )
。这会被转换为内核响应的中断调用。
这两种对操作系统发出请求的方式是不兼容的,因此您(通常)不能在UNIX系统上运行Windows可执行文件,反之亦然,而不使用一些充当转换层的其他系统,如WINE,VMWare等(虽然这两种工作的方式非常不同)。
(顺便说一句,a.out
没有说明可执行文件的内容;它是在UNIX系统上编译的可执行文件的传统文件名,是“汇编程序输出”的缩写.GCC允许交叉编译,所以你可以甚至可以使用它编译与Win32兼容的.EXE文件。您可以使用-o
标志来指定输出文件名,这表明它与输出文件的实际格式没有关系。)
答案 2 :(得分:1)
在unix环境中,任何设置了+ x位的文件都被认为是可执行文件。请记住,即使非二进制文件也可以执行(shell脚本,批处理文件等)。 Windows依赖于文件扩展的概念,在Unix上我们只设置chmod +x filename
。
您始终可以使用-o file
标志来强制gcc生成您喜欢的任何文件名。