| 首页 | 技术文章 | 软件下载 | 博客 | 论坛 | 精品教程 | 黑客动画 | 视频资源 | 在线服务 | 黑客游戏 | 

您现在的位置: 中国X黑客小组 >> 技术文章 >> 编程技术 >> 程序设计 >> 文章正文 用户登录 新用户注册
  [图文]开发 Windows 64 位版本应用程序的简介         ★★★ 【字体:
开发 Windows 64 位版本应用程序的简介
作者:未知    文章来源:msdn    点击数:    更新时间:2006-2-26    

开发 Windows 64 位版本应用程序的简介

发布日期: 09/02/2004 | 更新日期: 09/02/2004

Microsoft Corporation

适用于:
Microsoftt_ Windows Server™ 2003

摘要: 通过引入 64 位的操作系统,Microsoft 已经将 Windows 环境提升到了新的水平。Windows 64 位版本是企业级的操作系统,可以运行在高端系统上,例如内存为 16 TB、处理器多达 64 个的 Intel_ Itanium_ platform。将现有的应用程序从 Windows 32 位版本迁移到 Windows 64 位版本相对来说并不费力气,即使允许两个版本同时从相同的代码库中构建也是如此。Windows API 所提供的现有功能与高性能的 Intel Itanium 平台结合使用可以使开发人员利用他们现有的 Windows API 知识来构建可伸缩的、企业级应用程序。

*

下载 SimpleWebServerSample.exe。

本页内容

Itanium 概述 Itanium 概述 Windows 64 位版本简介 Windows 64 位版本简介 Windows 64 位版本的 C/C++ 编程 Windows 64 位版本的 C/C++ 编程 常规 Windows 编程 常规 Windows 编程 小结 小结 资源 资源

Itanium 概述

EFI:Itanium 的 BIOS

Itanium 的 BIOS 并不是您通常熟悉的个人计算机的 BIOS。可扩展固件接口 (EFI) 是将操作系统从 BIOS 和硬件中分离出来的抽象层。EFI Shell 与 Windows 中的命令提示符很相似。在某些方面,EFI Shell 就像是一个内置的小型操作系统。从 EFI Shell,您可以访问驱动器(包括 CD-ROM)、运行可执行文件(例如 Windows 的安装程序),甚至可以执行简单的文本编辑。系统配置数据存储在非挥发性内存中,而不是存储在硬盘上,并且可以通过 EFI Shell 进行配置。

EPIC:Intel 的顺序处理器

Itanium 是一种顺序处理器,意味着它会以指令提供的顺序来执行这些指令。这与普通的 x86 处理器不同,x86 处理器在可能的情况下会在管线中重新排序指令,然后尝试并行执行指令。对于 Itanium 而言,编译器必须明确地排序指令,然后负责检查指令之间的相互依存关系。编译器还必须负责通知处理器可以并行执行的指令。Intel 有一个为此定义的新术语:EPIC。EPIC 表示明确并行指令集计算。它负责编译器执行所有优化。处理器将不会进行任何重新排序。这使得编译器责任更加重大,稍后将在本文中进行讨论。

执行单元

Itanium 由九个执行单元组成,如下所示:

两个整数单元

两个整数/负载存储单元

两个浮点单元

三个分支单元

Itanium 具有一个十阶管线,负责提取、解码和执行指令。Itanium 最多可以同时处理六条指令。

寄存器

Itanium 具有多达 328 个寄存器:128 个 64 位整数通用寄存器、128 个 82 位浮点寄存器、64 个 1 位谓词寄存器、8 个分支寄存器以及用于各种目的的其他寄存器的集合,例如 x86 后向兼容性(当运行在 x86 兼容模式中时,Itanium 会将一些 x86 寄存器映射到 64 位寄存器上,同时提供专门用于处理器的 x86 模式的其他寄存器)。

要协助管理如此大量的寄存器,Itanium 有能力同时设计和轮换寄存器。我们将通用寄存器分成两组:前 32 个寄存器是固定的、全局寄存器。后 96 个寄存器可以用于设计和轮换。

寄存器设计

ALLOC 指令用于建立寄存器框架。寄存器框架将物理寄存器(硬件)映射到逻辑寄存器(软件)上,这样当调用某个函数时,不再需要推出或弹出所有参数,编译器就可以为子例程分配一定范围的寄存器,其中的一些寄存器可能会映射到父例程的寄存器上。可以在两者之间重叠的寄存器用于传递参数。这样比将参数推出和弹出到堆栈上更为有效。当然,推出和弹出参数的传统方法仍然可以使用。

由于前 32 个寄存器是固定的,您无法设计它们。因此,可以设计的寄存器的最大数量为(其余的)96 个寄存器。另外,只有整数寄存器可以设计,浮点寄存器和谓词寄存器不能进行设计。

寄存器轮换

寄存器也可以轮换或转移到一个或多个位置。在解开循环时,这可能很有帮助,因此使用不同的物理寄存器,在不相互干预的情况下,那些周而复始地在相同的寄存器集中运行的循环可以同时运行。利用这个选项,编译器可以更进一步改进指令的并行处理。

指令集

IA-64 指令是 41 位长的指令。指定 128 个通用寄存器中之一需要使用七位,并且指定两个源寄存器和一个目标寄存器,一共是 21 位。每条指令可以指定 64 个谓词寄存器中的一个,再加上 6 位。这占用了 27 位,而我们尚未指定实际的操作代码。

指令封装到 128 位的“绑定”中。其中三条指令(123 位),再加上 5 位模板字段。然后,这些绑定会被汇编到“组”中。组是理论上可以同时执行的指令集合。组中的指令没有相互依存关系。在编译时,编译器必须对此进行计算并对绑定一起分组。处理器将不会再次检查编译器的工作,所以编译器必须保证其正确。组可以是任意的长度。模板字段中的一位表示组的结束。

绑定和组是不同的。绑定是指令分派到处理器的方式。Itanium 的总线和解码电路为 128 位宽,刚好用于 3 条指令(Itanium 实际上同时分派两个绑定)。组是指令进行交互的逻辑方式。

有关 Itanium 平台和 IA-64 体系结构的详细信息,请访问 Intel Itanium Web site。有关开发针对 Itanium 平台软件的详细信息,请参阅 Intel Itanium Developer Center。

返回页首返回页首

Windows 64 位版本简介

它只是 Windows API

Microsoft_ Windows Server™ 2003 64 位平台并不要求您了解新的 API 就可以利用 64 位环境的好处。并没有出现 Win64 API,它仍然是熟悉的 Win32 API(现在更合适的名称为 Windows API)。出现了一些新的兼容 64 位的数据类型,因此您可能需要对代码进行少量的更改。关键的一点是所有现有的 Win32 知识都可以直接应用到 Windows 64 位版本中,并且您的大部分代码都可以针对 64 位平台进行编译,而无需更改。这也意味着您可以从单个代码库构建代码的 32 位和 64 位版本,减少了由于维护两个代码库所带来的维护开销。

但是,在两个操作系统版本之间存在着非常重要的一些差异,这一点需要注意。Microsoft 已经去除了一些旧的组件,例如 Win16 子系统—Windows 64 位代码不支持16 位的 Windows 版本。也不支持 POSIX 和 OS/2 子系统。不过,出现了一个新的子系统,称为 WOW64。

WOW64

WOW64 是 Windows-32-on-Windows-64 的缩写。它为现有的 32 位应用程序提供了 32 位的模拟,可以使大多数 32 位应用程序在无需修改的情况下运行在 Windows 64 位版本上。它类似于旧的 WOW32 子系统,负责在 Windows 32 位版本下运行 16 位的代码。

硬件本身具有 32 位兼容性模式,可以处理 IA-32 指令的实际执行,而 WOW 层处理诸如在 32 位和 64 位模式之间切换处理器以及模拟 32 位系统的事务。例如,32 位和 64 位程序具有不同的注册表配置单元。还有一个用于 32 位二进制文件的不同的系统目录。64 位二进制文件仍然使用 System32 目录,因此,当 32 位应用程序安装到系统中时,WOW 层会确保将 32 位二进制文件置于一个新的目录 SysWOW64 中。这是通过如下方式实现的:根据应用程序是否运行在 WOW 下,截获对 API 的调用(如 GetSystemDirectory)并返回适当的目录。相同的问题可能会存在于注册表中。因为 32 位和 64 位的 COM 服务器都可以安装在系统上,并位于相同的类标识符 (CLSID) 下,因此 WOW 层需要将对注册表的调用重定向到适当的 32 位或 64 位配置单元中。WOW 层也会处理注册表中某些区域之间的镜像更改,以便使其更简单地支持 32 位和 64 位代码之间的交互操作。

WOW64 非常重要,因为当不关注性能和可伸缩性的问题时,它使您可以利用大多数现有的 32 位代码。它是两种方法的最佳结合。您可以将您的服务迁移到 64 位,同时将 Microsoft 管理控制台 (MMC) 配置管理单元保留为 32 位。Windows 64 位版本包括 MMC 的 32 位和 64 位的版本。当选择保留管理工具为 32 位时,进程间的通讯可能会遇到某些问题,但是只要接口设计正确,诸如远程过程调用 (RPC) 的协议应该可以在 32 位和 64 位进程之间运行。有关 WOW64 的另外一点需要牢记:它并不是为要求高性能的应用程序而设计的。至少,WOW64 子系统需要将 32 位参数扩展到 64 位,并且需要将 64 位的返回值截断为 32 位。在最糟糕的情况下,WOW64 子系统将需要进行内核调用,涉及到的不仅仅是到内核的转换,还有从处理器的 32 位兼容性模式到其本机 64 位模式的转换。在 WOW64 下运行时,应用程序将无法妥当地进行调整。对于那些您要将其保留为 32 位的应用程序而言,请在 WOW64 下测试它们。如果性能不能满足您的期望,您需要考虑将应用程序迁移到 64 位。

WOW64 是在用户模式下实现的,作为 ntdll.dll 和内核之间的层。WOW64 及其支持的一些 DLL 仅仅是可以加载到 32 位进程中的 64 位的 DLL。对于所有其他情况,进程保持为纯进程。32 位的进程无法加载 64 位的 DLL,反之亦然。

有关 WOW64 的详细信息,请参阅 Microsoft_ Platform SDK 中的“64-bit Windows Programming - Running 32-bit Applications”。

虚拟内存和地址空间

默认情况下,Windows 32 位版本的地址空间限制在 4 GB,其中一半是为内核保留的。这限制了普通的应用程序只能使用 2 GB 的有效虚拟内存。2 GB看起来好像很多,但是由于错误的分配算法、大型文件映射甚至过多的使用 DLL,地址空间很容易在应用程序中变得零碎。看一下任务管理器中的“VM Size”列,就会发现普通应用程序消耗的虚拟内存量。当然,就想过去的 DOS 时期(利用 XMS/EMS)一样,有很多种方法可以使 32 位的应用程序访问多于 4 GB 的物理内存。进入物理地址扩展 (PAE) 和地址窗口扩展(Address Windowing Extensions,AWE)。PAE 通过将地址位的数量从 32 扩展到 36 来工作,这样使应用程序可以寻址的空间达到 64 GB。AWE 使应用程序可以将大于 4 GB 的物理内存范围映射到虚拟地址空间中。这两种方法都引入了开销并增加了代码的复杂性。

Windows 64 位版本提供 16 TB 的有效寻址空间,其中一半可用于用户模式的应用程序。这意味着整个数据库可以移动到内存中,显著地提高了性能,或者整个网站可以缓存到内存中。它还可以使代码保留并委托到巨型的邻近虚拟内存块中,无需实际地担心虚拟内存碎片问题。这也考虑到了巨型文件映射对象或共享的内存部分。

返回页首返回页首

Windows 64 位版本的 C/C++ 编程

/WP64:使编译器警告您潜在的问题

Microsoft_ Visual C 和 Microsoft_ Visual C++_ .NET 2002 编译器添加了 /WP64 开关,这使您可以测试 32 位代码的 64 位兼容性问题。编译器将发出有关指针截断和不正确转换的警告。将 32 位应用程序迁移到 Windows 64 位版本中前面的一个步骤就是打开这个标记,然后就像通常编译代码那样来编译您的代码。第一次会有几个错误。例如,请看下面这个代码片段:

DWORD i = 0;

size_t x = 100;



i = x; // C4267: warning C4267: '=' : conversion from 

    // 'size_t' to 'DWORD', possible loss of data.

在 32 位的平台上,这段代码能够很好的进行编译,因为 size_t 是 32 位的,但是在 64 位的平台上,size_t 就是 64 位的整数。启用 /WP64 后,编译器将会警告您类似的情况。

其他示例:

void func(DWORD context)

{

  char* sz = (char*)context; // C4312: warning C4312: 

                // 'type cast' : conversion 

                // from 'DWORD' to 'char *' of

                // greater size

  // Do something with sz..

}



char* string = "the quick brown fox jumped over the lazy dog.";



func((DWORD)string); // C4311: warning C4311: 'type cast' :

           // pointer truncation from 'char *' 

           // to 'DWORD'

在修复这些错误后,请测试您的 32 位代码。您希望确保 32 位的代码继续按预期那样工作。32 位和 64 位二进制文件应该从相同的代码库中构建。这就是编写不断前进的 Windows 应用程序的关键概念。开始时,您需要考虑 32 位和 64 位的问题,并且为应用程序编写可以运行在这两个平台上的代码。

新的数据类型

Windows 64 位版本使用 LLP64 数据模型。这意味着标准 C 类型 int 和 long 保持为 32 位整数。数据类型 size_t 将映射到处理器词大小(IA32 为 32 位,IA64 为 64 位),并且 __int64 是 64 位整数。在协助迁移 32 位代码时就会完成上述操作。意义在于您可以对应用程序的 32 位版本和 64 版本使用相同的代码库。

还有一个称为 LP64 的数据模型,它将标准的 C 类型 long 映射到 64 位整数,并使 int 保持为 32 位的整数。这种数据模型常见于 Unix 平台,但从单个代码库同时创建应用程序的 32 位和 64 位版本时可能有一些困难。您可能注意到了此处的常见主题。32 位平台与 64 位平台的思想就是应该能够从单个代码库中构建两个版本的应用程序。如果无法做到,那么您可能要重新审视您的设计。具有单个代码库就是巨大的胜利,尤其是如果您计划发行两个版本。

多态类型

由于 Win32 API 是针对 C 的,在很多情况下,您都需要将整数转换成指针或者相反。在 32 位的硬件上不会有问题,其中指针的大小和整数的大小是相同的,但在 64 位的硬件上却完全不一样。这就是多态类型出现的原因。

对于特定的精度,您可以使用固定精度的数据类型。不管处理器的词大小如何,它们的大小都是一致的。大多数这些类型都在它们的名称中包含精度,可以从下面的表中看出:

表 1. 固定精度的数据类型 类型 定义

DWORD32

32 位无符号整数

DWORD64

64 位无符号整数

INT32

32 位有符号整数

INT64

64 位有符号整数

LONG32

32 位有符号整数

LONG64

64 位有符号整数

UINT32

无符号 INT32

UINT64

无符号 INT64

ULONG32

无符号 LONG32

ULONG64

无符号 LONG64

此外,当您需要数据类型的精度随着处理器词大小变化时,请使用指针精度数据类型。这些类型又称为“多态”数据类型。这些类型通常以 _PTR 后缀结尾,如下面的表格所示:

表 2. 指针精度的数据类型 类型 定义

DWORD_PTR

指针精度的无符号长类型

HALF_PTR

指针大小的一半。用于包含一个指针和两个小型字段的结构中

INT_PTR

指针精度的有符号整型

LONG_PTR

指针精度的有符号长类型

SIZE_T

指针可以引用的最大字节数。用于必须跨指针的整个范围的计数

SSIZE_T

有符号 SIZE_T

UHALF_PTR

无符号 HALF_PTR

UINT_PTR

无符号 INT_PTR

ULONG_PTR

无符号 LONG_PTR

LPARAM

与 LONG_PTR 为同义词,(在WTypes.h 中定义)

WPARAM

与 UINT_PTR 为同义词,

[1] [2] [3] 下一页

文章录入:IceRiver    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    Skype用户须警惕新Windows蠕
    McAfee发布Windows Mobile风
    Windows Vista对付ARP病毒有
    非主流入侵之会话劫持winnt/
    US CERT:谷歌eBay雅虎网站均
    微软今日发布Windows Live测
    微软报告称操作系统漏洞 今年
    Windows平台的Cisco VPN 客户
    微软将开放Windows Live网络
    微软DirectX开发包存缺陷
      网友评论:(只显示最新5条。评论内容只代表网友观点,与本站立场无关!)
    Powered by ICE RIVER - STUDIO
    » CnXHacker.CoM   © CopyRight 2002-2006, CnXHacker.CoM™, Inc. All Rights Reserved.