献给c/c++的同学。它包括创建一个64位安全的应用程序或者是从32位迁移到64系统的所有步骤。该介绍一共包括28课,涉及的内容有64位系统,64位应用程序的构建,如何找64位代码的问题和如何优化。
第一课:64位的系统是什么
在写这个课程的时候,有2个流行的微处理器的64位架构:IA64和Intel64.
1、IA-64:是Intel和Hewlett Packard 共同研发64位处理。他是在安腾和安腾2微处理器上实现的。要了解更多关于IA64的架构请看维基的Itanium(http://en.wikipedia.org/wiki/Itanium)
2、Intel 64(EM64T / AMD64 / x86-64 / x64):兼容x86的一个架构,他有很多的名字,入x86-64,AA-64,AMD64,yamhill技术,EM64T,IA-32e,Intel64,x64。他们指的都是同一件事情。详情可看x86-64(http://en.wikipedia.org/wiki/X86-64)
接着我们就要说IA-64和Intel64这两种完全不同的,不兼容,微处理架构。考虑到Intel64(x64/AMD64)架构师windows软件开发者最床用的,因而我们后面提到的windows操作系统,指的是Intel64架构下的65位应用程序。例如:windows XP的x64版的,vista X64,WIN7 x64。我们简称他们为win64.
Intel 64架构
以下的内容是根据“AMD64 Architecture Programmer's Manual. Volume 1. Application Programming”第一卷来写的
Intel64是一个过时的x86架构的一个简单而强大的扩展,并向后兼容x86.他添加了64位地址空间,并且支持过时的16位和32位的应用程序代码和操作系统;你也可以不需要重新编译他们来保证在Intel64上运行。
64位架构的决定是源于“应用程序需要大的地址空间”的这个需求。首先,他可以诞生出高性能的服务器、数据管理器、CAD、游戏等。应用程序能从64位地址空间里获得更多的寄存器和地址空间。过时的x86只有少数的寄存器从而限制了计算机的性能。x64的寄存器的增加有利于提高应用程序的性能。
x86-64的主要优点如下:
*64位的地址空间
*扩展的寄存器集合
*熟悉的命令集合
*32位应用程序可以在64位的操作系统下启动
*兼容32位的操作系统
64位操作系统
几乎所有的现代的操作系统都有Intel64的版本。例如MS的Win XP x64。大的Unix开发者也会推出64位的版本,例如LInux Debian 3.5 x86-64.但是他并不意味着该操作系统的所有代码都是64位的。操作系统的部分代码和很多应用程序仍然是32位不需要改变,因为Intel64是向后兼容的。因而,64位的版本用一个特殊的模式WoW64(windows-on-windows 64)来处理32位应用程序,使之能运行在64位操作系统上
地址空间
尽管64位处理器理论上能够寻址2的64次方的字节的地址,Win64现在只支持16T字节(也就是2的44次方)。因为当代的处理器只能获取到1T字节(2的40次方)的物理内存。架构最多能够扩展到2^52字节的空间(不是依靠硬件哦)。而且这种情况下你需要极多数量的页表来实现它。
除了这个限制外,每个特定版本的64位windows能获得的内存大小是依赖于MS的商业原因的。不同的windows版本有不同的限制,如下表
Win64程序模型
和win32类似,win64的页大小也是4KB。地址空间的起始的64KB从来都不能使用,因而正确的最低的地址是0X10000.不像win32,系统的dll能获得比4GB更多的空间。
Intel 64的编译器有一个特性:他们充分利用寄存器来作为参数传给函数,而不是用栈空间。这就使win64架构的开发者摆脱调用约定(calling convertion)的概念。在win32里,你会用到各种调用约定,如__stdcall,__cdecl,__fastcall等。在win64里,只有一种调用约定。以下是通过寄存器来传递4个整数类型的例子:
*RCX:第一个参数
*RDX:第二个参数
*R8:第三个参数
*R9:第四个参数
参数里开头的4个整数会这样传给栈。传递浮点数参数时,使用的是XMMO-XMM3寄存器。
调用约定的不同导致在一个程序里不可能既使用64位的代码,又使用32位的代码。换句话说,如果应用程序是以64位的模式编译的,所有的dll都必须是64位的。
通过寄存器传递参数是让64位程序比32位快的一项改革。你通过使用64位的数据类型也许能获得额外的性能。我们接下来要讲的第二课就是:在64位的windows环境下使用32位的应用程序(待续)