x86/x64体系探索及编程
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

前言

2003年前后,我开始对x86平台的一些架构知识产生了浓厚的兴趣,在业余时间断断续续地学习了AMDSystem Programming手册。后来,为了方便,索性挑了些感兴趣的章节打印出来,偶尔拿出来翻翻。也曾通过写一个OS来学习x64的体系知识,当然这个OS只是个试验品。

在计划好写本书之后,我又好好地重读了Intel的几卷手册,特别是Intel 64 and IA-32 Architectures Software Developer's ManualVolume 3 System Programming GuideVolume 1 Basic Architecture

因此,本书所写的内容是基于Intel处理器的,至于所测试机器的处理器则是IntelWestmere微架构处理器(SandyBridge的上一代)。但是,如非明确注明,大部分内容对于AMD处理器也是适用的,有些地方甚至反复多次对IntelAMD的区别进行了强调。

尽管我已竭力探索事物的本质真相,然而不可否认,本书中仍可能会有些个人主观的认知因素,但必须说明的是,这些主观的认知是经过客观的实验事实而得出的,本书的每个知识点都经过了实验例子进行测试。在本书成书过程中,我慢慢地发现,如果没有经过实验的测试竟然觉得心里不踏实,总觉得欠缺什么而不敢下笔。本书中有上百个实验,每个章节都有数个例子。然而比起我所做过的测试仍相距甚远。

通过本书,我希望能引起读者的共呜,激发求知的欲望和探索的精神,以及学会怎样“肓人摸象”。尽管摸到的可能只是事实的一部分,但是只要我们不断地进行摸索,经过反复的测试,我们终将会慢慢积累知识,在一无所知的情况下逐步接近真相。

本书特色

本书是对Intel手册所描述的处理器架构进行探索和论证,每个章节都有相应的测试实验,所运行的实验例子可以在真实的机器上执行。部分实验是不能在VMware虚拟机和bochs模拟器上进行的,必须要在真实机器上运行。例如:第3篇的绝大部分内容和第4篇的部分内容。

通过阅读本书,大约能培养自己动手实验的能力。由于本书的实例是在祼机(无OS环境)上运行,因此,如果能走完本书的例子,加上一些OS知识的处理,基本上就可以写出自己简易的OS核心。

关于x86与x64

本书的另一个特色是无缝地集成了对x86x64体系的描述。因此,既适合于x86体系,也适合于x64体系。这是因为,x64是在x86的基础上扩展而来的64位技术,x64体系有x86的全部内容,又增添了全新的long-mode工作模式与64位执行环境。

在现在的技术趋势下,为什么还要保留对x86体系的描述?一方面,这能满足不同的读者层;另一方面,也是最重要的原因:x64体系并不是一个全新的平台架构,而是基于x86架构扩展而来的。因此对x64的描述绝不能脱离x86架构,x64体系还保留着向下兼容的能力,在long-mode64位执行环境里,许多情况下仍然可能使用常见的32位编程技术,这主要是因为,在64位执行环境里,尽管default address size(默认地址大小)是64位,然而绝大部分指令的default operand size(默认操作数大小)依然是32位。

从软件编程的角度上看,Pointer(指针)值是属于64位的(地址宽度为64位),但是integerlong仍属于32位(默认的数据宽度为32位),除非明确数据使用64位的long long类型访问,64位执行环境里指令使用REX prefixREX扩展操作数前缀)来达到访问64位的数据宽度。

当然,如果只把它看成一本描述x64体系的书籍,那也是没问题的!即使是Intel官方的手册里也是同时在对Intel64IA-32架构进行描述。

本书内容

本书共分为五大篇。

续表

续表

读者对象

如果你工作在x86x64平台上;如果你对x86x64架构知识有兴趣;如果你正在学习x86x64,或者有一定的基础,想继续扩展视野:我想本书是适合你阅读的。

本书假设你有一定的x86基础知识,包括:

1)有一些汇编语言的基础,至少能看懂一些简单的汇编代码。

2)有一些x86架构知识,知道x86是什么。譬如:知道什么是实模式、保护模式等。

3)最好能有一些写boot代码的知识。即使没有,你也可以参照书中的源代码例子。

尽管书中例子是使用汇编语言编写,但即便你的汇编语言基础不那么好,阅读起来也不会感到太困难,因为这些例子的代码并不像从高级语言反汇编出来的代码那样涉及过多的程序结构知识,譬如:

1)你不会面对着stack的各种开栈销栈处理,因为实验例子中的过程调用基本上不会使用栈来传递参数。

2)你不会面对着各种复杂的程序分支结构和编程技巧,实验例子都使用很纯粹的汇编代码编写。

了解一下nasm

如果你对汇编语言掌握比较熟练,你可能需要去了解一下nasm汇编语法,因为本书的所有实验例子都使用nasm编译器编译。别担心,对一条汇编代码,nasm的语法和Intel使用的语法是一样的,但对于操作数寻址到内存,则表达形式有一些差异。你可以从http://www.nasm.us/xdoc/2.10.03/html/nasmdoc0.html这个在线文档了解nasm简单的语法。

nasmIntel在内存操作数寻址的表达上有一些区别,主要有以下两方面。

1)operand size(操作数尺寸)的指示字。

2)segment override prefix(段改写前缀)的位置。

Intel语法上:

mov dword ptr [eax],1    ; 操作数尺寸使用dword ptr指示字
mov eax,cs:[20100h]    ; 段前缀放在[]括号外

而在nasm语法上则需要变通一下:

mov dword [eax],1     ; 操作数尺寸指示字去掉ptr字
mov eax,[cs:20100h]    ; 段前缀放在[]括号内

另外,例子中也有使用宏定义,因此也需要注意一下nasm中宏的定义方式,如下所示:

%macro NMI_DISABLE 0   ; 由 %macro 开始,参数个数为 0......
%endmacro      ; 由 %endmacro结束

选择章节阅读

如果想对x86x64有较全面的了解,那么从第1章到第21章最好都去阅读。对于x86x64编程基础不是那么好的读者,第1章和第2章是必须要去了解的。

要想更好地了解x86x64平台,第1篇、第2篇,以及第4篇是需要好好阅读的,它们是x86x64架构体系的基石。

第3篇与第5篇旨在帮助读者扩展视野,它们是让x86x64平台变得强大的地方。

x86与x64的章节

在每一个章节里都会有x86x64体系的相关描述,特别是在第2篇和第3篇。如非明确注明,x86下大多数的特征在x64下也是适用的。譬如对MSR(Model-Specific Register)的访问方式在64位执行环境下与x86体系下是一样的;再譬如对local APIC的编程方式,在x64下与x86下也是一样的;又譬如对x87 FPUSSE指令的执行环境,大多数情况下在x64下与x86下是一样的。

总之,除了第12章明确描述x64内容外,其他章节都会含有x86x64的描述。

书中的例子与工具

本书共21章,每一章对应一个topicXX目录,实验例子源代码就在这些目录下以ex开头的子目录里,有上百个实验例子。书中示例可在http://www.broadview.com.cn/18176下载,也可以在www.mouseos.com/books/x86-64/index.html下载。

下载解压后即可在\source目录下看到前面所说的目录结构和实验源代码,还可以看到每个实验生成的软盘映像文件(demo.img)及硬盘映像文件(c.img),其中的硬盘映像文件可以直接写入到U盘,放在真实机器上进行测试。

此外,在\tools目录下还包括了我写的merge工具及其源代码和开源的dd工具。merge工具是一个合并模块写入映像文件以及U盘的工具。由于所附merge工具是在Windows 7下编译的,如果在您的平台下不能使用,您可以使用Visual Studio重新编译生成。

dd工具也可以用来写入U盘,但我很少使用它,不过我们可以用它来查看U盘设备在Windows上的符号链接名字,例如:\\.\g:就是在我的机器上的U盘符号链接名,在您的机器上应该是不同的名字。

参考资料

IntelIntel®64 and IA-32 Architectures Software Developer's Manual,即Intel64IA-32架构软件开发者参考手册,共有三卷,可从Intel官方网站免费下载:http://www.intel.hk/content/www/xa/en/processors/architectures-software-developer-manuals.html

AMDAMD64 Architecture Programmer's Manual,即AMD64架构编程手册,共有五卷,可从其官方网站免费下载:http://developer.amd.com/documentation/Pages/default.aspx

只要您有耐心,它们都是不二之选。

致谢

感谢电子工业出版社博文视点编辑及相关工作人员的辛勤劳动使本书得以出版,感谢谭文先生作序,感谢罗云彬先生推荐。

邓志

2012年8月