据我所知,32 位程序使用 FLAT 内存模型,64 位也使用。使用 32 位程序只有 4GB 可以寻址,而使用 64 位(例如 rcx)可以使现代 CPU 提供的 40 到 48 个地址位饱和并寻址更多。
所以除了这个和一些 32 位处理器没有的额外控制寄存器之外,我问自己是否有可能在 linux 中完美地运行 32 位代码。
我的意思是我执行的每个 C 代码都必须是 64 位的吗?
我可以理解,由于 C 构建在堆栈帧和基指针上,将 32 位基指针插入堆栈,因此我引入了堆栈指针为 64 位的问题,并且可能会以 32 位方式访问弹出和推送操作代码。
那么在运行 64 位 Linux 内核时有什么区别,是否有可能实际运行 32 位代码?
[更新]
为了清楚地说明场景,我正在运行一个 64 位程序并将一个 ELF64 文件加载到内存映射所有内容并直接调用该方法。这个想法是动态生成 asm 代码。
最佳答案
它们之间的主要区别在于不同的调用约定。在 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。
异常处理是基于64bit数据的;在 32 位上,它是基于代码的。因此,在 64 位上,对于展开异常,不再使用指令来构建异常框架。异常处理完全基于数据,因此不需要额外的指令来尝试/捕获。
32 位应用程序的内存限制为 2GB(或在 32 位 Win 操作系统上的应用程序上使用/LARGEADDRESSAWARE 3GB,或在 64 位 Win 操作系统上为 4GB)现在要大得多 More on https://msdn.microsoft.com/en-us/library/windows/desktop/aa366778(v=vs.85).aspx
当然,通用寄存器有 64 位宽度而不是 32 位。因此,任何整数计算都可以处理大于 0..4294967296 的 32 位限制的值。 (签名-2147483648..+2147483647)
同样读写内存用一个简单的MOV指令可以一次读写一个QWORD(64bit);在 32 位上只能写入 DWORD(32 位)。
一些说明已被删除:PUSHA + POPA 消失了。 并且现在使用INC/DEC的一种编码形式作为REX-Byte前缀编码。
关于c - 32 位和 64 位汇编程序之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29538742/