如果32位和64位CPU之间的唯一区别是它们的寄存器大小那么为什么必须为64位平台重写32位程序?

Cel*_*tas 11 language-agnostic cpu assembly cpu-word

在编写64位程序时,源代码的实际差异是什么?比如只是组装不同?它不像64位版本的C++.如果它比编译器上的选项简单,那么更多的程序本身不是64位?如果32位与64位CPU的唯一区别是寄存器大小,我看不出它如何影响程序(除了能够处理更多内存).

Fra*_*kH. 17

32位/ 64位移植的典型缺陷是:

  1. 程序员隐含的假设sizeof(void*) == 4 * sizeof(char).
    如果你正在做这个假设并且例如以这种方式分配数组("我需要20个指针,所以我分配80个字节"),你的代码在64位上中断,因为它会导致缓冲区溢出.

  2. "小猫杀手"(re @ SK-logic),int x = (int)&something;(反之亦然void* ptr = (void*)some_int).再一次假设sizeof(int) == sizeof(void*).这不会导致溢出但会丢失数据 - 指针的高32位,即.

    这两个问题都是一个称为类型别名的类(假设在两种类型之间的二进制表示级别上存在标识/可互换性/等价性),并且这种假设很常见; 像UN*X,假设time_t,size_t,off_t正在int,或在Windows上,HANDLE,void*long可以互换的,等等.

  3. 关于数据结构/堆栈空间使用的假设(参见下面的5.).在C/C++代码中,局部变量在堆栈上分配,由于下面的要点,在32位和64位模式之间使用的空间不同,并且由于传递参数的规则不同(32位x86通常在堆栈上,64位x86部分在寄存器中).在32位上使用默认堆栈大小的代码可能会导致64位堆栈溢出崩溃.
    这很容易被发现作为崩溃的原因,但取决于可能难以修复的应用程序的可配置性.

  4. 32位和64位代码之间的时序差异(由于不同的代码大小/缓存占用空间,或不同的存储器访问特性/模式,或不同的调用约定)可能会破坏"校准".说,for (int i = 0; i < 1000000; ++i) sleep(0);32位和64位可能会有不同的时间......

  5. 最后,ABI(应用程序二进制接口).64位和32位环境之间通常存在比指针大小更大的差异...
    目前,存在64位环境的两个主要"分支",IL32P64(Win64使用的 - int并且longint32_t,只是uintptr_t/ void*uint64_t,根据来自大小的整数来说话<stdint.h>)和LP64(什么UN*X使用- intint32_t,longint64_tuintptr_t/ void*uint64_t),但有在不同的排列规则"细分",以及-一些环境假设long,floatdouble在各自的尺寸一致,而其他人认为他们在倍数对齐四个字节.在32位Linux中,它们以四个字节对齐,而在64位Linux中,float对齐为四个,long并且double为八个字节的倍数.
    这些规则的结果是,在许多情况下,sizeof(struct { ...})即使数据类型声明完全相同,bith 和结构/类成员的偏移量在32位和64位环境之间也是不同的.
    除了影响数组/向量分配之外,这些问题还影响数据输入/输出,例如通过文件 - 如果32位应用程序写入例如struct { char a; int b; char c, long d; double e }同一应用程序重新编译64位读取的文件,结果将不是所希望的.
    刚才所举的例子是只有约语言原语(char,int,long等),但当然也影响到各种平台依赖性/运行库的数据类型,是否size_t,off_t,time_t,HANDLE,基本上任何平凡struct/ union/ class... -所以错误的空间这里很大,

然后是较低级别的差异,例如手动优化组装(SSE/SSE2/...); 32位和64位具有不同(数量)的寄存器,不同的参数传递规则; 所有这些都强烈影响了这种优化的执行方式,并且很可能需要重写/需要增强在32位模式下提供最佳性能的SSE2代码以提供最佳性能的64位模式.

还有代码设计约束,对于32位和64位非常不同,特别是在内存分配/管理方面; 一个经过精心编码的应用程序"最大限度地利用它可以获得的32位内存"将会有关于如何/何时分配/释放内存,内存映射文件使用,内部缓存等的复杂逻辑 - 其中大部分将会在64位有害,你可以"简单地"利用巨大的可用地址空间.这样的应用程序可能会重新编译64位就好了,但是比一些"古老的简单弃用版本"更糟糕,它没有所有最大化的32位窥视孔优化.

所以,最终,它也是关于增强/增益,而这是更多的工作,部分是在编程中,部分在设计/需求中.即使你的应用程序在32位和64位环境中干净地重新编译并在两者上都经过验证,它实际上是受益于64位?是否可以/应该对代码逻辑进行更改以使其在64位中更快/更快地运行?你能否在不破坏32位向后兼容性的情况下进行这些更改 没有对32位目标的负面影响?增强功能将在哪里,您可以获得多少?
对于大型商业项目,这些问题的答案通常是路线图上的重要标记,因为您的出发点是一些现有的"赚钱机器"......


Mar*_*tin 7

并非所有程序都必须重新编写才能在64位平台上运行.通常,程序会被重写,以便利用某些64位操作系统上可用的更大自由,例如更大的地址空间,但这并不意味着必须重写它们才能工作.

某些程序可能需要重新编译,保持源代码不变.一些使用中间表示和即时编译的编程环境允许相同的二进制文件在32位或64位操作系统上保持不变.

在需要重写本机程序的地方,通常是由于对指针大小的假设,正如其他答案所述.有些人可能会称这些假设错误.


Ign*_*ams 5

它们有不同的内存对齐问题,加上许多新手程序员假设32位一切(指针大小,文件偏移,时间戳大小等).