购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.4 寄存器

寄存器为处理器提供了高速访问数据的途径。由于寄存器在物理上位于CPU内部,它们的延迟远低于内存,因为内存请求需要经过总线和桥接器才能访问数据。

在32位架构中,寄存器(register)包含32位的数据,就像程序中的变量一样。每个寄存器都有一个独特的名称,当参与运算或从内存加载新值时,寄存器中的数据可以被修改。

寄存器的主要限制在于,它们的数量有限,必须被整个程序共享。如果程序用完了寄存器,就需要开始在内存中储存信息,这将对性能产生不利影响。有限的寄存器数量意味着正常的执行周期如下:

●从内存中获取数据并将其存储在寄存器中。

●处理数据。

●将数据保存回内存。

2.4.1 x86中的寄存器

如前所述,寄存器是CPU中的一种特殊名称和位置,允许进行非常快速的操作。所有的寄存器可以被分为两种不同的类别。

●通用寄存器(General-Purpose Register,GPR):用于一般数据、地址等的存储,并且可以直接操作。

●特殊寄存器(Special-Purpose Register,SPR):用于存储程序状态。

x86架构定义了许多寄存器,如图2.5所示。然而,其中许多寄存器被CPU自身所保留,我们只需要了解其中一部分即可。

图2.5 x86寄存器

来源:Liam McSherry/Wikimedia Commons/CC BY-SA 3.0.

1.通用寄存器

通用寄存器在应用程序中承担了大部分重要的工作,负责存储从内存中获取的数据,进行数据处理,并存储计算结果。下面给出了x86中最重要的通用寄存器,每个通用寄存器都可以存储32位的数据。每个累加器都有一个传统角色并且以角色命名。但是,通用寄存器可以被用于任何目的,你可以在任何寄存器中放置计数器,而不仅仅是在ecx寄存器中放置。

eax

eax被称为“累加器”寄存器,常被用来保存算术运算的结果。例如,程序可能会执行计算eax+=ebx。

ebx

ebx是“基址”寄存器。它通常被用来存储用于保存变量的内存块的基址。例如,表达式[ebx+5]可以被用来访问数组的第五个元素。

ecx

ecx是“计数器”寄存器,传统上用于计数。例如,ecx可能被用来跟踪循环的当前迭代。在命令for(i=0; i<10; i++)中,变量i可能会被存储在ecx寄存器中。

edx

edx是“数据”寄存器,常被用来存储数据。例如,应用程序可能会包含指令sub edx, 7,这条指令的功能是把edx寄存器的值减7。

esi

esi是“源索引”寄存器(源变址寄存器)。传统上,它用于存储源数组中的索引。例如,在指令array[i]=array[k]中,k的值很可能被存储在esi中。

edi

edi是“目标索引”寄存器(变址寄存器)。它用于存储目标数组的索引。例如,在指令array[i]=array[k]中,i的值很可能被存储在edi中。

ebp

ebp是“基址指针”寄存器。它的功能是存储当前栈帧的基址。程序栈和栈帧的概念将在后续章节进行探讨。

esp

esp是“栈指针”寄存器。它储存了当前栈帧顶部的地址。

2.特殊寄存器

特殊寄存器用于特定任务,并且不允许直接修改。例如,指令mov eip, 1使用了一个特殊寄存器,不能进行汇编,而使用通用寄存器的指令mov eax, 1却可以进行汇编。

eip

eip是“指令指针”寄存器,用于存储下一条要执行的指令的地址。

eflags

eflags是“标志”寄存器。它存储标志,这些标志的值为真或假,保存着系统状态和先前执行指令的结果的信息。

提示: 通用寄存器可以读取和写入,但是特殊寄存器只能读取,不能写入。

2.4.2 寄存器的使用

在汇编过程中,通用寄存器可以被当作变量来处理,并通过名称进行访问。例如,指令mov eax, 1将数值1存到eax,而add eax, ebx则将eax的内容加到ebx上。

请注意,所有这些寄存器的名称都以字母e开头。这是因为这些32位寄存器是从原始的16位寄存器中“扩展”出来的。

寄存器内容的低位部分可以通过从名称中删除这个e来访问。例如,ax寄存器包含了eax寄存器的低16位。

如果寄存器的名称以x结尾(如eax、ebx、ecx和edx),那么这个16位寄存器可以进一步划分为两个8位寄存器,它们分别被标识为l和h。al包含寄存器ax的低8位,而ah包含了高8位。这在图2.6中有所说明,其中eax=0x01234567,ax=0x4567,ah=0x45,al=0x67。

图2.6 eax寄存器的各个部分

64位寄存器

在64位的x86架构中,所有的指令和行为与32位的x86一样。不过,64位的架构有更多、更大的寄存器。

图2.7展示了64位x86常用的寄存器。除了有所不同的32位寄存器外,64位架构还包括标记为r8~r15的八个寄存器。

所有的64位寄存器都比它们的32位版本要大。对于32位x86中存在的寄存器,比如eax,它的全64位版本就会把e换成r,变成rax寄存器。这样,就可以通过32位的名称获取寄存器的低32位,像ax、al、ah这样的名称的用法保持不变。

对于像r8这样的新寄存器,64位的x86支持对其低32位、低16位和低8位的访问。这些分别被标记为r8d、r8w和r8b,如图2.8所示。 GbLd6b+Ri+RyUcfakkdo/WfFKjRTuIoUIy4uuov8cELvzWcfY0tJ5QajPCq5L/Cs

点击中间区域
呼出菜单
上一章
目录
下一章
×