3.3 80x86基本架构
Intel的CPU一般归类于冯·诺依曼(Von Neumann)结构。冯·诺依曼计算机系统主要包含3大部分:中央处理单元(CPU)、内存和输入/输出(I/O)设备。这3个组件通过系统总线(包括地址总线、数据总线和控制总线)相连。图3-1给出了其相互关系。

图3-1 冯·诺依曼计算机系统模块图
CPU向地址总线放入地址值,以此选择内存单元位置或I/O设备端口位置,从而与内存和外设通信。这些内存单元或端口位置在系统中占有唯一的二进制地址值。然后CPU、内存和I/O设备通过数据总线互相传递数据。控制总线里的信号线控制着数据进出内存或I/O设备的方向。
3.3.1 寄存器
寄存器组是CPU内部最突出的特性。几乎所有的80x86 CPU操作都涉及至少一个寄存器。例如,要将两个变量的值加起来,结果放入第三个变量中,必须将其中一个变量放入寄存器,对其加上第二个操作数,然后将结果送入目标变量。寄存器差不多是每个操作的中介。因此在80x86汇编语言程序中,寄存器是必不可少的。
80x86 CPU的寄存器可以分成4类:通用寄存器、特殊目的寄存器(应用可访问)、段寄存器和特殊目的核心模式寄存器。由于段寄存器在Windows、BSD、BeOS和Linux等现代32位操作系统中不怎么用,而特殊目的核心模式寄存器是用来编写操作系统、调试器和其他系统级工具的,这些软件的构建方法已超出了本书范围,所以我们不再考虑段寄存器和特殊目的核心模式寄存器。
3.3.2 80x86通用寄存器
Intel的80x86 CPU家族为应用程序提供若干通用寄存器,包括如下8个32位寄存器:
EAX、EBX、ECX、EDX、ESI、EDI、EBP、ESP
每个寄存器名的“E”前缀表示“扩展(Extended)”,以便将这些32位寄存器与下列16位寄存器区分开来:
AX、BX、CX、DX、SI、DI、BP、SP
80x86 CPU还提供如下8个8位寄存器:
AL、AH、BL、BH、CL、CH、DL、DH
特别要注意的是,这些通用寄存器并非各为一体,即80x86并不提供24个单独的寄存器,而是将32位寄存器与16位寄存器重叠,后者又重叠以8位寄存器。图3-2给出了其相互关系:

图3-2 Intel 80x86 CPU的通用寄存器
因此实际修改某个寄存器内容时,可能没有特别指明就改动了三个寄存器的值。例如,修改寄存器EAX也许会改变寄存器AL、AH和AX的值。我们将会经常看到编译器所产生的代码用到80x86的这种特性。举个例子,编译器会清除(置0)寄存器EAX的所有位,然后将AL设为1或0,以便得到一个32位的True(1)或False(0)值。有的
机器指令只操纵AL寄存器,而程序也许需要以EAX返回这些指令的结果。利用寄存器重叠的优点,编译器产生的代码就能够通过操纵AL的指令而返回整个EAX值。
虽然Intel将这些寄存器称作“通用寄存器”,但不能因此就以为它们可用于任何目的。比如说,寄存器SP/ESP就有着专门用途,切勿挪作它用,因为它是堆栈指针。类似地,寄存器BP/EBP也是专用的,无法当作通用寄存器使用。所有80x86寄存器都有各自的特殊意图,仅可在特定环境下使用。在讨论使用这些寄存器的机器指令时,我们会考虑这些特殊用法的,请参看在线资源。
3.3.3 80x86的EFLAGS寄存器
32位EFLAGS寄存器将许多单一比特位的布尔值(True/False)或标志位集合在一起。这些比特位中的大部分要么为操作系统的核心模式函数保留,要么与应用程序员没有太大关系。应用程序员只要会以汇编语言代码读写其中8位即可——溢出标志位、方向标志位、中断禁止位[1]、符号标志位、零标志位、辅助进位标志位、奇偶标志位和进位标志位。图3-3展示了这些标志位在寄存器EFLAGS低16位中的布放位置。

图3-3 80x86标志寄存器低16位的布局
应用程序员可用的这8个标志位中,4个具有特别价值:溢出标志位、进位标志位、符号标志位和零标志位。我们将这4个标志位称为“条件码(condition code)”。每个标志位都有一个状态——要么是设置(1),要么是清除(0),可以用来检验上次运算的结果。例如在比较两个值后,条件码标志可告诉我们其中一个值是小于、等于还是大于另一个值。






