![x86汇编与逆向工程:软件破解与防护的艺术](https://wfqqreader-1252317822.image.myqcloud.com/cover/730/53287730/b_53287730.jpg)
2.4.1 x86中的寄存器
如前所述,寄存器是CPU中的一种特殊名称和位置,允许进行非常快速的操作。所有的寄存器可以被分为两种不同的类别。
• 通用寄存器(General-Purpose Register,GPR):用于一般数据、地址等的存储,并且可以直接操作。
• 特殊寄存器(Special-Purpose Register,SPR):用于存储程序状态。
x86架构定义了许多寄存器,如图2.5所示。然而,其中许多寄存器被CPU自身所保留,我们只需要了解其中一部分即可。
![](https://epubservercos.yuewen.com/2FAC88/31751360804058606/epubprivate/OEBPS/Images/37_01.jpg?sign=1739614311-smnZbPFVDOKYnkoIW2nw4zYbzDgpFnaw-0-400bbcd974fc70bf62005272033a5476)
图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是“标志”寄存器。它存储标志,这些标志的值为真或假,保存着系统状态和先前执行指令的结果的信息。
提示:通用寄存器可以读取和写入,但是特殊寄存器只能读取,不能写入。