通用语言运行时库(CLR)的变化 CLR已经作了内部的修改以支持64位计算,在很大程度上,此修改涉及到代码生成、垃圾回收、例外处理、和调试等等。
![]()
·代码生成。64位版本的CLR需支持64位本地应用程序的开发,这通常意味着对每一个新平台,都必须重新构建一个Just-In-Time(JIT)编译器,也就是大家所看到的IA64与x64平台。
·垃圾回收。64位处理器可寻址更大的内存,突破了32位系统中存在的4GB内存界限。因此,垃圾回收机制也必须作相应修改,以支持更大的内存。
·例外处理。在对最终用户的使用方法保持不变的前提下,64位系统的例外处理已经彻底修改并重写。
·调试。调试器依赖于代码生成与例外处理子系统,因为一旦这两个子系统变了,调试器也必须跟着改变。
开发工具 在Visual Studio 2005中,Visual C++ .NET、Visual C#、Visual Basic .NET已经支持64位应用程序的开发,而作为Visual Studio 2005另一个组成部分的Visual J#却不支持。图9描述了在Visual Studio 2005中对不同语言的支持,及这些托管语言所支持的平台环境。

图9:Visual Studio 2005中的语言及平台支持
Visual Studio 2005集成开发工具仍会作为32位程序发布,并在WOW64系统下运行。大多数在32位平台上具有的功能,在64位平台上同样也具有,但要注意的是,此处没有"编辑并继续(Edit and Continue)"功能。
除了Visual Studio 2005,Windows Platform SDK同样也提供了64位编译器工具集,其中包含了一个可用于开发64位应用程序的Visual C++编译器。
预防性措施 在开发64位本地应用程序之前,有必要弄清楚:我们到底应采取哪些步骤,以保证今天的程序将来可移植到64位?
在此,可参考以下一些预防性措施或使用一些工具,例如,Visual C++编译器支持/Wp64选项,以探测当前代码中存在的潜在移植性问题。
另外,在Visual Studio 2005的集成开发环境中,还有一个类似的工具--FxCop,通过在FxCop中加入一些规则,便可在编译时探测到移植性问题。
在托管语言方面,以下情况涉及到移植性问题:
·涉及COM Interop与平台调用的Interop相关代码:本地64位程序不能加载32位COM DLL,这就是说,一个64位的进程不能转变为32位代码,并在同一进程中成为一个32位DLL的宿主程序;不同处理器架构间的Interop也不能在同一进程中做到这一点。因此,当一个64位程序必须要调用COM DLL时,此COM DLL最好也是64位的。
·在许多情况中,这些COM DLL是第三方代码,所以你可能没有源代码。如果这样的话,程序就必须针对x86架构重新构建,并且运行于WOW64子系统中。还有一个解决的办法,在另一个单独的32位进程中加载此32位的DLL,由64位程序对此进行RPC调用。
·浮点数的相等比较。不能保证同一IL中间语言代码在32位与64位平台上有相同的结果,因此,推荐不要直接进行浮点数的相等比较。浮点数在64位计算机上的表示法基于IEEE-754标准,其允许差分计算,这会对那些对精度要求非常高的金融程序与图形程序带来很大的影响,必须重新设计算法以应对此问题。有关更多信息,请参考:http://docs.sun.com/source/806-3568/ncg_goldberg.html
·使用StrUCtLayout属性对结构数据排列方式的显式控制。属性StructLayout可应用于结构和类,当它被显式地指定时,必须精确地控制非托管内存中对象的每一个成员的位置。相对于32位平台,因为数据类型长度有所变化,所以结构的打包也有所不同,因此,必须避免显式地控制结构的排列方式。
·对数字的位操作。C#提供了位操作符,包括了AND、OR、左移位和右移位操作符。对数据类型的位操作,在32位与64位计算机上会有所变化,这是因为平台间数据类型的内部表示方法会有所不同。
·自定义串行化。 .NET Framework对串行化提供了两个选项--通过使用Serializable属性实现自动串行化,或对类型实现ISerializable接口达到自定义串行化的目的。当使用 .NET Freamwork提供的最基本的串行化机制时,不会发生什么问题,然而,当通过ISerializable实现自定义串行化时,得出的结果会因为32位与64位平台而有所不同,具体依赖于为实现自定义串行化而采用的方法。 当然,也许程序中会多次用到涉及上述的功能,在这种情况下,必须分别构建和测试32位与64位版本的程序。进入讨论组讨论。
使用Visual Studio 2005进行开发 回头再看,Visual Studio 2005可支持64位应用程序的开发,其所支持的平台如表2中所示。
平台
描述
AnyCPU
生成不依赖于特定平台的程序集,通常称为"可移植程序集"
x86
生成针对x86平台的32位程序集
x64
生成针对x64平台的64位程序集
Itanium
生成针对Itanium平台的64位程序集 表2:针对不同平台,Visual Studio 2005所支持的64位程序开发
在编译程序期间,可在"工程"的"属性页"中设置目标平台,属性页包括一个构建栏,可以让你指定相关的平台。例如在图10中,C#和VB.NET的编译器选项为"/platform",在VB.NET中,也可在"高级编译器设置"对话框中找到同样的选项。图11中所示的目标CPU下拉框允许设置程序所需的特定CPU类型。

图10:编译器目标平台可选项

图11:目标CPU下拉框
当然,使用特定的设置依赖于特定的情况:
·AnyCPU选项生成平台无关程序集,这也是集成开发环境(IDE)的默认设置。一个通过AnyCPU选项编译的程序集可毫无问题地运行在x86、x64及Itanium平台上,而生成的程序集基于PE32格式(PE32是所有EXE及DLL用到的格式)。
·x86选项用于生成特定于32位Intel x86兼容处理器平台的代码。所生成的程序集同样也基于PE32格式,可运行于WOW64子系统中。
·x64选项用于生成特定于x86处理器架构的64位本地程序的代码。所生成的程序集基于PE32 {+}格式(其为现有PE32格式的扩展),只能运行在64位x64架构的计算机上。
·Itanium选项用于生成特定于Itanium(IA-64)处理器架构的64位本地程序的代码。所生成的程序集同样也基于PE32 {+}格式,只能运行在基于64位Itanium的计算机上。
也许开发出来的程序不必运行在所有的平台上,因此,就不必构建成一个平台无关的程序,这样的话,开发过程中就能充分利用诸如 #define、#if之类的预编译指令,可以用这些预编译指令带上条件编译常量,来包装针对特定目标平台的代码。
以下是推荐的条件编译常量:
·_AMD64_ 用于针对AMD64平台的代码
·_IA64_ 用于针对IA64平台的代码
·_WIN64_ 用于指定任一64位Windows平台代码
加载一个 .NET可执行文件
在编译生成可执行文件时,指定的编译器选项会被嵌入到所生成PE32或PE32{+}可执行文件中。而PE32{+}格式是PE32格式的扩展,含有关于机器类型的更多信息。
在PE32中,CLR头包括一些额外的标志,如:ILOnly和32BitRequired,ILOnly只出现在当平台被设置为AnyCPU时,而32BitRequired出现在平台被设置为x86时,而当平台被设置为x64或Itanium时,就会生成嵌入了机器相关信息的可执行文件。
OS Loader(操作系统加载器)根据这些设置来加载相应的可执行文件,图12演示了OS Loader加载可执行文件时的控制流程。

图12:OS Loader(操作系统加载器)加载可执行文件的流程
当OS Loader发现可执行文件为PE32 {+}时,会把它作为一个64位进程加载;如果不是,接下来会检查ILOnly标志,如果也没有,则会使用WOW64子系统把它作为一个32位可执行文件加载。
当设置了ILOnly标志时,会进一步地检查是否32BitRequired标志也设置了,如果是,也会被WOW64子系统加载,否则,将重映像为PE32+,并作为一个64位程序加载。
那程序速度更快了吗? 大多数人在想到64位计算时都会问同样一个问题:64位程序与32位程序相比,是不是更快一些呢?这也许是关于64位技术的一个误区,对此的回答是:"也许吧"。这样回答的原因是,程序的速度或者说性能,基于许多的因素,不可能立马下结论表示64位程序一定就更快。64位计算的好处在于,它打开了更先进软件设计的大门--这些软件能充分利用64位处理器访问更大的内存、在单个时钟周期能处理更多的数据,相对于类似的32位程序,新生的64位程序可表现出惊人的效果。
业界的64位趋势 许多Windows软件开发商,现在已开始发布基于64位Windows的软件产品了。
·AMD发布了一个Windows上的性能分析器--AMD Code Analyst,参见http://www.amd.com/ us-en/Processors/DevelopWithAMD/0,,30_2252_869_3604,00.html
·InstallShield 10.5已支持64位程序的安装。参见http://www.installshield.com/downloads/installshield/aag.pdf
·Compuware发布了名为"DevPartner64"的64位DevPartner Studio。参见http://www.compuware .com/products/devpartner/64.htm
·针对AMD64平台的Java 2 Platform Standard Edition 5.0 (J2SE)现在也可以获取了。参见http://javashoplm.sun.com/ECom/docs/Welcome.jsp?StoreId=22&PartDetailId=jdk-1.5.0-rc-windows-amd64-JPR&SiteId =JSC&TransactionId=noreg
·硬件生产商也为它们的产品发布了64位的驱动程序。此处可找到一个完整的列表:http://www.amd.com/us-en/Processors/ DevelopWithAMD/0,,30_2252_875_10454,00.html;其中NVIDIA已经为它的全系列GPU与nForce 4芯片组发布了64位驱动程序。
·游戏总是会用到最新最强大的硬件,例如Unreal Tournament (http://www.amd.com/ us-en/Processors/ProductInformation/ 0,,30_118_10220_9486%5E9621~75301,00 .html)、Far Cry (http://www.amd.com /us-en/Processors/DevelopWithAMD/ 0,,30_2252_875_10543,00.html)、和Shadow Ops: Red Mercury (http://www.amd.com/us-en/Processors/ ComputingSolutions/0,,30_288_11054_ 11705,00.html)。(Shadow Ops的64位增强版本http://www.atari.com/shadowops/us/amd.html)
总而言之,64位Windows将会带领我们进入一个崭新的64计算时代,让我们一起期望这一天的早日到来。进入讨论组讨论。