假设我想为平台编译C程序。我知道我必须在编译中指定CPU架构,因为不同CPU架构之间的指令集不同。我也知道我必须指定目标平台操作系统,因为不同操作系统之间的可执行文件结构和系统调用之间存在差异。
Q1:问题是,如果我需要指定32位或64位的操作系统(不是CPU架构)吗?
换句话说,假设我有两个系统:
编译上述系统的程序有什么不同吗?
Q2:当我在-m32
编译器的选项中添加gcc
时,这个32
是什么用的?它是用于操作系统还是用于CPU架构?
答案 0 :(得分:5)
问题是,如果我需要指定32位或64位的OS(不是CPU架构)吗?
您没有指定Operating System(您在给定计算机上只运行一个操作系统;要运行其中一些操作系统,请使用hypervisor或某些VM)。你指定&选择Application Binary Interface(ABI),因为某些操作系统能够提供多个ABI(和runtime systems)。
编译上述系统的程序有什么不同吗?
是的,存在一些差异(至少考虑sizeof(void*)
; 64位ISA使用更多寄存器,ABI可以通过向寄存器传递更多参数来定义不同的调用约定)。我无法详细讲述Windows,我不知道。
当我在gcc编译器的选项中添加-m32时,这32是什么用的?
深入了解GCC的文档,特别是Invoking GCC章。
有些x86 option:
-m32选项将int,long和指针类型设置为32位,并生成在任何i386系统上运行的代码。
-m64选项将int设置为32位,将long和指针类型设置为64位,并为x86-64体系结构生成代码。对于Darwin,只有-m64选项还会关闭-fno-pic和-mdynamic-no-pic选项。
另请阅读x32 ABI(这是Linux特定的事情)。
我无法详细说明特定于Windows的内容(我不知道也从未使用过)。但我将解释Linux上发生的事情。我让您为您的专有Microsoft操作系统寻求类似的知识。
在Linux上,可以配置操作系统kernel(在内核构建时)以接受32位和64位ELF可执行文件,并为两种体系结构提供system call运行时环境。这样的内核能够使用execve(2) 32位可执行文件和64位可执行文件执行,并提供两个不同的ABI s(一个用于-m32
用于686 instruction set architecture,另一个用于executables {1}}对于x86-64 ISA)。请注意,相同的 OS内核可以在32位或64位模式下执行二进制686。
我不了解Windows,但我可以想象微软还提供两种不同的运行时环境。 ABI,一个用于32位x86-64 ISA,另一个用于64位x86 calling conventions ISA。也许其中一个是可选的,需要单独安装或购买(我真的不知道,我也不在乎)。
您可以深入了解Microsoft文档以查找差异的详细信息。
另见Operating Systems : Three Easy Pieces wikipage。
我建议阅读类似x86-64(可自由下载,逐章)的内容,以便更多地了解操作系统的角色,以及更多关于long mode ISA的内容,包括coupling。
当然,您需要关注其他依赖项(或DLL hell)。阅读dependency hell& @SultanLegend's answer