寄存器总结

16个寄存器可以被分成以下四类:

​ 8个通用寄存器(General-purpose registers)

​ 6个段寄存器(Segment registers)

​ 程序状态与控制寄存器(EFLAGS)

​ 指令指针寄存器(EIP register)

一、通用寄存器:

32位CPU通用寄存器共有8个:EAX,EBX,ECX, EDX,ESI,EDI,EBP,ESP

第1- 4个寄存器:

  • EAX:累加寄存器,是操作数和结果数据的累加器

  • EBX:基址寄存器,指向DS段中数据的指针

  • ECX:计数寄存器,是字符串和循环操作的计数器

  • EDX:数据寄存器, I/O指针

上面4个寄存器主要用于算术运算(ADD/SUB/XOR/OR等) 指令中,常用来保存常量与变量的值

变址寄存器(第5-6个):

  • ESI:(字符串操作源指针)源变址寄存器

  • EDI:(字符串操作目的指针)目的变址寄存器

ESIEDI与特定的串操作指令(MOVS/LODS/STOS)一起使用,在字符串操作的时候用的比较多

变址寄存器存放存储单元在段内的偏移量,用它们可实 现多种存储器操作数的寻址方式,为通过多种方式访问 存储单元提供便利

指针寄存器(第7-8个):

  • ESP:栈顶指针寄存器,用于存放当前堆栈的栈顶 地址,专门用作堆栈指针,不可作为一般通用寄存 器使用

  • EBP:栈底指针寄存器(基址指针寄存器),表示 栈区域的基地址,永远指向当前函数栈的栈底位置, 不可作为一般通用寄存器使用

二、段寄存器:

  • CS:Code Segment,代码段寄存器 – 存放应用程序代码所在段的段基址

  • DS:Data Segment,数据段寄存器 – 用于存放数据段的段基址

  • SS:Stack Segment,堆栈段寄存器 – 用于存放栈段的段基址

  • ESFSGS,附加数据段寄存器 – 用于存放程序使用的附加数据段的段基

三、程序状态与控制寄存器(标志寄存器)

在IA-32中标志寄存器的名称为EFLAGS,大小为4个字节, 共有32个位元,每个位数都有其作用,;

可以分为以下四类:

  • 系统标志(位8,9,14,16,17,18,19,20,21)和 IOPL(I/O Privilege Level)字段(位12,13) : 控制操作系统或执行操作,应用程序不能修改以上标志位
  • 方向标志(DF,位10):控制串操作指令的处理方向 :DF=0,从低地址到高地址 DF=1,从高地址到低地址
  • 状态标志(位0,2,4,6,7和11):表示算数指令的运 算结果,如ADD、SUB、MUL和DIV指令 :和应用程序运行状态密切相关,需掌握
  • 预留标志位(位1,3,5,15,22-31) :DO NOT US

状态标志(位0,2,4,6,7, 和11) :

(重点)

  • CF(位0) – 进位标志位:

    一般情况下,在进行无符号数运算的时候,它记录了 运算结果的最高有效位向更高位的进位值,或从更高位的借位值。 – 在加法运算中,若运算结果从字或字节的最高位产生了进位,则 CF=1;否则CF=0 – 在减法运算中,若被减数无借位,则CF=0;否则CF=1

  • OF(位11) – 溢出标志位:

    一般情况下,OF记录了有符号数运算的结果是否发生 了溢出 – 如果发生了溢出,OF=1;如果没有发生溢出,OF=0 – 注:CF和OF所表示的进位和溢出,是分别针对无符号数和有符号数 运算而言的,一定要分清楚CF和OF的发生条件 (2)寄存器 — 程序状态与控制寄存器

  • AF(位4) – 辅助进位标志位:

    在发生以下情况时,辅助进位标志AF的值被 置为1,否则其值为0: » 在字操作时,发生低字节向高字节进位或借位时 » 在字节操作时,发生低4位向高4位进位或借位时

  • PF(位2) – 奇偶标志位:

    记录相关指令执行后,其结果的最低有效字节中1 的个数是否为偶数 – 如果1的个数为偶数,PF=1;如果1的个数为奇数,PF=0 (2)寄存器 — 程序状态与控制寄存器

  • SF(位7) – 符号标志位:

    记录相关指令执行后,其结果是否为负 – 当操作数为有符号数时,若结果为负数,SF=1;若结果为非负数, SF=0

  • ZF(位6) – 零标志位:

    记录相关指令执行后,其结果是否为0;若运算结果 为0,则其值为1,否则其值为0

四、指令指针寄存器

​ 程序运行时,CPU会读取EIP中一条指令的地址, 将指令传送到指令缓冲区后,EIP的值自动增加

​ CPU每次执行完一条指令,就会通过EIP寄存器 读取并执行下一条指令

​ 不能直接修改EIP的值,只能通过其他指令间接 修改 – 这些特定指令包括JMP、JC、CALL、RET – 可以通过中断或异常来修改EIP的值