通用寄存器
- EAX 用于操作数和结果数据的累加器(int $0x80软件中断,用于决定执行具体的系统函数)
- EBX 指向数据内存段中的数据的指针
- ECX 字符串和循环操作的计数器
- EDX I/O指针
- EDI 用于字符串操作的目标的数据指针
- ESI 用于字符串操作的源的数据指针
- ESP 堆栈指针
- EBP 堆栈数据指针
其中,EAX、EBX、ECX、EDX寄存器可以通过16位和8位名称引用。
段寄存器
段是一种内存保护技术,把内存划分多个段,并为每个区段设置起始地址,范围,访问权限等,以保护内存,此外,还同分页技术一起用于将虚拟内存变更为实际物理内存.段内存记录在SDT(Segment Descriptor Table 段描述符表)中,而段寄存器存储SDT的索引(index),IA-32处理器允许3种不同的访问系统内存的方法:
- 平坦内存模式:把全部系统内存表示为连线的地址空间,所有指令、数据和堆栈都包含在相同的地址空间中,通过称为线性地址的特定地址访问每个内存位置。
- 分段内存模式:把系统内存划分为独立段的组,通过位于段寄存器中的指针进行引用,每个段用于包含特定类型的数据,例如一个段用于包含指令,另一个段包含数据,另一个段包含堆栈。
- 实地址模式:把所有段寄存器都指向零线性地址,并且不会被程序改动,所有指令、数据和堆栈元素都是通过线性地址直接访问。
CS 代码段
DS 数据段
SS 堆栈段
ES 附加段指针
FS 附加段指针
GS 附加段指针
每个段寄存器都是16位,包含了指向内存特定段的起始位置的指针,逻辑地址由段地址和偏移地址构成,处理器把逻辑地址转换为相应的线性地址,以访问内存的字节。
程序调试中会经常用到FS寄存器,用于计算SEH(Structured Exception Handler 结构化异常处理机制),TEB(Thread Environment Block 线程环境块),PEB(Process Environment Block 进程环境块)等地址
指令指针寄存器
EIP 指令指针寄存器(也称程序计数器,不能直接修改,必须通过程序控制指令改变)
- 在平坦内存模式下,指令指针指向下一条指令码的内存位置的线性地址
- 在分段内存模式下,指针指令指向逻辑内存地址,通过CS寄存器的内容引用
控制寄存器
CR0 控制操作模式和处理器的状态的系统标志
CR1 当前没有使用
CR2 内存页面错误信息
CR3 内存页面目录信息
CR4 支持处理器特性和说明处理器特性能力的标志
- 不能直接访问控制寄存器的值,可以把控制寄存器中的数据传送到通用寄存器,就可以查看当前运行的任务操作状态,也可以修改后,传送到控制寄存器中。
标志寄存器
EFLAGS 标志寄存器
- 状态标志
标志 位 名称
CF 0 进位标志(无符号整数数学操作产生最高位的进位或者借位)
PF 2 奇偶校验标志(结果寄存器中1的位+奇偶标志位=奇数个1)
AF 4 辅助进位标志(二进制编码的十进制数学操作运算的寄存器第3位发生进位或借位)
ZF 6 零标志(如果操作结果为零,零标志就被设置为1)
SF 7 符号标志(结果的最高有效位,表明结果是正值还是负值)
OF 11 溢出标志(符号整数运算结果的正值过大,或者负值过小) - 控制标志
DF 字符串处理方向标志(为1,字符串指令自动递减内存地址,为0,字符串自动递增内存地址) - 系统标志
标志 位 名称
TF 8 陷阱标志(为1,启用单步调试模式)
IF 9 中断使能标志
IOPL 12和13 IO特权级别标志(当前运行的任务的I/O特权级别,必须小于或等于,否则拒绝访问)
NT 14 嵌套任务标志(是否链接到前一个执行任务,用于链接被中断和被调用的任务)
RF 16 恢复标志(控制处理器在调试模式中如何响应异常)
VM 17 虚拟8086模式标志(为1,虚拟8086模式中操作,而不是保护模式或实模式)
AC 18 对准检查标志(与CR0寄存器的AM位一起,用于启用内存引用的对准检查)
VIF 19 虚拟中断标志(虚拟模式时,起IF标志作用)
VIP 20 虚拟中断挂起标志(虚拟模式时,表示一个中断正被挂起)
ID 21 识别标志(表示处理器是否支持CPUID指令,如果能设置或清零,表示支持)
Intel和AT&T语法主要区别
- AT&T使用$表示立即操作数,而Intel的立即操作数不需要界定。
- AT&T标签名称前面的符号$指示汇编器使用内存地址,例如:movl $value, %edi,把标签引用的内存地址传送给EDI寄存器。
- AT&T间接寻址模式,例1:movl %ebx, (%edi),把EBX寄存器的值传送EDI寄存器中的内存地址。例2:movl %edx, 4(%edi),把EDX寄存器的值存放EDI寄存器指向的位置之后4个字节的内存位置中。
- AT&T在寄存器名称前面加上前缀%,而Intel不需要。
- AT&T语法处理源和目标操作数使用相反的顺序,例如把十进制4传送到EAX寄存器,AT&T语法为:movl $4,%eax,而Intel语法为:mov eax,4。
- AT&T语法在助记符后使用一个单独的字符来引用操作数的长度,而Intel语法中数据长度被声明为单独的操作数,例如:AT&T的指令movl $test,%eax等同于Intel语法的mov eax, dword ptr test。
- 长调用和跳转使用不同语法定义段和偏移值。AT&T语法使用ljmp s e c t i o n , section, section,offset,而Intel语法使用jmp section:offset。
变址内存模式
内存位置由下列因素确定:
- 基址
- 添加到基址上的偏移地址
- 数据元素的长度
- 确定选择那个数据元素的变址
表达式的格式:
base_address(offset_address ,index ,size)
其中任何值为零,都可以忽略它,但是仍需逗号作为占位符,offset_address和index的值必须时寄存器
获取的数据值位于:
base_address + offset_address + index * size
IA-32指令格式
IA-32指令由6部分组成,其中操作码项是必须的,其他项都是可选。
1、指令前缀:可选项,补充说明特定操作码含义
2、操作码:必选项,用来表示实际的指令,通常带有操作数,如寄存器、内存地址、常量等,指令中出现的ModR/M与SIB选项辅助操作码确定操作数
3、ModR/M:可选项,用来辅助说明操作码的操作数(操作数的个数、种类[寄存器、地址、常量])
4、SIB(Scale-Index-Base):可选项,用来辅助说明ModR/M,操作码的操作数为内存地址时,需要与Mod/M项一起使用
5、位移:可选项,操作码的操作数为内存地址时,用来表示位移操作
6、立即数:可选项,操作码的操作数为常量时,该常量被称为立即数