据我所知,32位程序使用FLAT内存模型和64位也是如此。使用32位程序,只有4GB的地址,使用64位(例如rcx)可以使现代CPU提供的40到48个地址位饱和,甚至更多。
除了这个和32位处理器没有的一些额外的控制寄存器之外,我问自己是否可以在linux中完美地运行32位代码。
我的意思是我执行的每个C代码必须是64位吗?
我可以理解,由于C构建在堆栈帧上,并且基指针在堆栈上推送32位基本指针,因此引入了堆栈指针为64位且可能以32位方式访问pop和push操作码的问题。
那么有什么区别,是否有可能在运行64位Linux内核时实际运行32位代码?
[更新]
要说明方案清楚,我正在运行64位程序并将ELF64文件加载到内存映射所有内容并直接调用该方法。我们的想法是动态生成asm代码。
答案 0 :(得分:3)
它们之间的主要区别在于不同的调用约定。在32位上有几种类型:__ stdcall,__ fastcall,...
在64位(x64)上只有一个(在Windows®平台上,关于其他我不知道的)并且它有一些要求,与32位非常不同。 有关https://future2048.blogspot.com的更多信息 请注意,ARM和IA64(Itanium)也是不同的编码,如x64(Intel64 / AMD64)
你还有8个通用寄存器r8..r15,带有子寄存器 r8d..r15d,r8w..r15w,r8b..r15b 对于基于SIMD的代码,还存在8个额外的寄存器xmm8..xmm15。
异常处理是基于64位的数据;在32位上它是基于代码的。因此,对于解除异常的64位,不再使用指令来构建异常帧。 exceptiom处理完全基于数据,因此try / catch不需要其他说明。
32位应用程序的内存限制为2GB(或者32位Win OS上的应用程序为/ LARGEADDRESSAWARE 3GB,64位Win OS上为4GB)现在要大得多 More on https://msdn.microsoft.com/en-us/library/windows/desktop/aa366778(v=vs.85).aspx
当然通用寄存器的宽度为64位而不是32位。因此,任何整数计算都可以处理大于32位限制0..4294967296的值。 (已签名-2147483648 .. + 2147483647)
使用简单的MOV指令读取和存储存储器也可以一次读写QWORD(64位);在32位上只能写一个DWORD(32位)。
删除了一些说明:PUSHA + POPA消失了。 INC / DEC的一种编码形式现在用作REX-Byte前缀编码。
答案 1 :(得分:0)
某些32位代码无需修改即可在64位环境中运行。但是,通常,函数不会起作用,因为调用约定可能不同(取决于体系结构)。根据程序的不同,您可以编写一些粘合剂来将参数转换为您想要的调用约定。因此,您无法将32位库链接到64位应用程序中。
但是,如果您的整个应用程序是32位,您可能可以正常运行它。内核的字大小并不重要。流行的操作系统都支持使用64位内核运行32位代码:Linux,OS X和Windows支持此功能。
简而言之:您可以在64位系统上运行32位应用程序,但是您无法在同一应用程序中混合使用32位和64位代码(除非深入了解)。