确保为32位Windows编写的程序与64位Windows兼容

11
虽然我理解程序在32位硬件/操作系统上编写的基本上没有任何理由不能在64位硬件/操作系统上运行,但实际上,我发现很多旨在为Windows 32位版本设计的程序无法在64位版本的Windows上运行。其中包括许多受欢迎的安全实用程序(来自诺顿和查克·波特的Zone Alarm等产品),以及一些游戏(我一直在尝试让《侠盗猎车手4》运行几个星期了,但无济于事 - 当然,这可能与与GTA4有关的其他问题有关,但这不是重点)。
我听说一个程序的不兼容性可能源于简单地不想从“Program Files(x86)”文件夹运行,但还有其他原因吗?为什么在32位系统上编写的病毒扫描器或防火墙无法在64位系统上运行?一切都应该向后兼容,那么为什么游戏不能运行呢?

这些侵入式应用程序会创建自己的驱动程序。如果您使用的是32位操作系统,则需要32位驱动程序。如果您使用的是64位操作系统,则需要64位驱动程序。Windows x64会尽其所能欺骗32位用户应用程序,让它们以为自己正在运行在32位Windows上。但是这种礼貌并不适用于驱动程序。事实上,按照规定,您应该为64位Windows构建64位版本的应用程序。曾经有一个旧版本的64位Windows XP是64位的,就像32位Windows是32位的一样。不能在32位操作系统上运行64位,反之亦然。但现在Windows做得更好了。 - Ian Boyd
8个回答

7

这个帖子上有很多错误信息。

当32位应用程序在64位Windows上运行时:

  • 大多数兼容性问题出现在应用程序尝试安装内核模式驱动程序时。32位驱动程序无法安装在64位操作系统上。这几乎肯定是防火墙的问题。它正在尝试钩取TCP/IP驱动程序堆栈。
  • 没有模拟器!32位目标代码由CPU完全本地执行,速度非常快。
  • 不支持旧的16位代码。这破坏了许多安装程序。
  • 访问正确的文件夹通常不是问题。当32位程序打开一个文件,比如%windir%\system32\,操作系统会自动将其重定向到%windir%\syswow64。对于注册表的某些部分也是如此。这里有一些潜在的陷阱,但通常是假设各种WINAPI Get...Directory()函数返回与Windows 95中相同的字符串。
  • 无论它是10年前编译的还是昨天编译的,C/C++指针仍然是32位(4字节),所有代码都假设这一点——包括SendMessage()!——仍然有效。只有在开始转换为64位编译器时才会出现8字节指针问题。

如果没有模拟器,那么Windows On Windows是什么? - biozinc
1
MSDN表示:在x64处理器上,指令由微架构本地执行。因此,在x64上的WOW64下执行速度与在32位Windows下的速度相似。在Intel Itanium处理器上,需要更多的软件来进行仿真,从而导致性能下降。 - Joseph
1
在x64处理器上,WoW不进行仿真。x64处理器能够同时运行x86和x64代码。它提供了32到64位Windows API调用的转换,并管理处理器处于32位还是64位模式时的情况。维基百科文章有来源:http://en.wikipedia.org/wiki/WOW64 - Eric Haskins
我开始认为虚拟化是更好的术语来描述WOW64在x64处理器上的工作原理。这个想法似乎与Virtuozzo的工作方式非常相似。 - Joseph
@biozinc。我真的不知道该怎么称呼它,但“模拟器”似乎意味着.exe文件的代码字节正在另一种架构上被解释或像Mac在Intel处理器上执行PowerPC程序一样实时翻译。至少大多数我认识的人都是这样认为“模拟器”的。 - Die in Sente

4
我找到的最好的解释在这里,基本上是说32位程序在模拟层上运行,这不允许系统访问你从64位环境中运行的本地程序所获得的访问权限。

http://blogs.msdn.com/oldnewthing/archive/2008/12/22/9244582.aspx

我会假设这意味着像GTA4这样的程序问题来自模拟层未能产生在32位本地系统上找到的预期结果。这就是为什么你总是看到微软发布兼容性更新的原因。
以下是MSDN对此事的说明:

http://msdn.microsoft.com/en-us/library/bb427430(VS.85).aspx


2
不!32位的Windows程序不能在64位Windows上的仿真器中运行!有一个Wow64层,重新解释系统调用,处理32位模式和64位模式之间的转换,重定向一些文件访问,但没有仿真器。当应用程序安装驱动程序时,问题就出现了。 - Die in Sente
1
我稍微调整了我的答案,但在 MSDN 上写着:“WOW64 是 x86 模拟器,它允许 32 位基于 Windows 的应用程序在 64 位 Windows 上无缝运行。”虽然我明白你的意思,但现在的用法中仿真可能更合适,但仿真这个词也能适用于模拟器。 - Joseph
@Die 在 Sente WoW 上确实对 IA-64处理器进行仿真,只是不支持x64。因此,这个答案在技术上是正确的,但在x64机器上,WoW更像是一个重定向层而不是仿真层。 - Eric Haskins

3

驱动程序与程序不同:

http://support.microsoft.com/kb/896456

Zone Alarm使用Check Point创建的特殊32位驱动程序进行监控。这可能是导致该应用程序出现问题的原因。至于《侠盗猎车手4》?我不知道。


GTA4:对于大多数游戏而言,反复制保护措施会安装驱动程序甚至是 root kit 以确保你的游戏是“合法”的。 - Remus Rusanu

2

可能有很多原因。

任何以低级别编程的应用程序都可能期望32位寄存器。由novatrust发布的Zone Alarm驱动程序就是一个很好的例子。GTA4可能会在多个点上使用汇编语言来提高性能,这可能导致任何问题,甚至只是在C++上假设32位。例如,看下面的代码:

struct GPoint
{
  int x;
  int y;
}

// Array of twenty GPoints
GPoint[] myArr = malloc(20 * sizeof(GPoint);

GPoint* myPointer = myArr;
int index = GetIndexAffectedPoint();

// Invert X and Y for the point
myPointer += 8*index;
swap(myPointer);

我知道这个例子相当幼稚,但无论如何,在这段代码中,你假设你的结构体长度为8字节(x整数占用4字节,y整数占用4字节),但在64位系统中实际上是两倍长,因此你最终会交换错误的点...这种情况在低级语言中经常发生,特别是在尝试提高性能时...


当你将32位代码重新编译为64位而没有修复这些假设时,这种情况就会成为一个问题。然而,问题是32位应用程序在64位操作系统上运行。在这种情况下,你示例中的旧代码将能够正常工作。 - Die in Sente


1

安全应用程序是一个不好的例子。它们都执行不支持的操作来对抗未记录的事情。从一个32位版本的Windows到下一个版本的更改足以破坏它们,更别说转移到64位。

话虽如此,在32位上有一些兼容性shim可以修复您的代码,但在64位应用程序上则无法实现。这是因为Microsoft假定您已经在64位上进行了测试。

其中一个结果是.NET应用程序。在32位系统上运行时,exe被jit到32位 - 在那里有兼容性shim来修复您的错误。如果您的客户碰巧在64位系统上运行,则可执行文件将被jit到64位,其中保护您免受自身影响的兼容性shim将不再存在。

Chris Jackson在他的博客中有一篇很好的文章:Shimming Applications on Windows Vista 64-Bit


1

问题可能是驱动程序。对于游戏来说,可能是某种肮脏的数字版权管理方案。尝试获取游戏的无光盘破解补丁,这样你就可以在没有数字版权管理的情况下运行它。


0

如果您正在使用文件系统或注册表,请确保您访问正确的文件夹。作为x86程序,您可能希望访问“Program Files(x86)”,“SysWOW64”,“WOW6232Node”等文件夹,而不是x64文件夹。

像诺顿和Check Point的Zone Alarm这样具有x86应用程序的产品无法运行其x86驱动程序,因为驱动程序需要x64才能被操作系统运行。


请不要直接访问那些文件夹。Windows已经将涉及常规目录的请求重定向到它们相应的32位副本。 - Powerlord

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接