1. 寄存器、内存和寻址

1.寄存器和内存

寄存器(Register)是 CPU的组成部分,是有限存储容量的告诉存储部件,用来暂存指令、数据和地址。一般的IA-32即x86架构的处理器中包含以下几个寄存器:

  • 通用寄存器:EAX、EBX、ECX、EDX、ESI、EDI。
  • 栈顶指针寄存器:ESP、栈底指针寄存器:EBP。
  • 指令计数器:EIP(保存下一条即将执行的指令的地址)。
  • 段寄存器:CS、DS、SS、ES、FS、GS。
对于x86-64架构,在以上寄存器基础上,将前缀的E改成R,以标记64位,同时增加了R8~R15这八个通用寄存器。

除此之外,CPU中还存在一个标志寄存器,其中的每位表示对于标志位的值,常用标志位如下:

  • AF:辅助进位标志,当运算结果在第3位时置1;
  • PF:奇偶校验标志,当运算结果的最低有效字节有偶数个时置1;
  • SF:符号标志,有符号整型的符号位为1时置1,代表是负数;
  • ZF:零标志,当运算结果为全0时置1;
  • OF:溢出标志,当运算结果在被操作数是有符号数且溢出时置1;
  • CF:进位标志,运算结果向最高位以上进位时置1,用来判断无符号数的溢出。
2.CPU的寻址方式

寻址方式

示例

操作对象

立即寻址

1000h

1000h这个数字

直接寻址

[1000h]

内存地址1000h的单元

寄存器寻址

RAX

RAX这个寄存器

寄存器间接寻址

[RAX]

以RAX中存的数作为地址的内存单元

基址寻址

[RBP+10h]

将RBP中数作为基址,加10h,访问这个地址的内存单元

变址寻址

[RDI+10h]

RDI中数字为基址+10h,访问这个地址的内存单元

基址加变址寻址

[RBX+RSI+10h]

……

2.x86/x64汇编语言

x86和x64汇编指令的基本格式:操作码 [操作数1] [操作数2]

es版CPU查询_指针

3. 反汇编

汇编语言中的条件跳转指令:

es版CPU查询_内存管理_02


反汇编的两种算法:线性扫描反汇编算法递归下降反汇编算法线性扫描法从代码起始片段开始一个接一个地解析指令,直到结束;缺点是一旦有新数据插入到代码段中,后续的反汇编结果均为错误的。递归下降法则会尝试推测每条代码的执行结果。

4. 调用约定

x86 32位调用约定

  • __cdecl:参数从右向左依次入栈,调用完毕,由调用者负责将这些压入栈的参数清理,返回值置于EAX中。
  • __stdcall:参数从右向左依次入栈。同上。
  • __thiscall:为类方法专门优化的调用约定,将类方法的this指针放在ECX寄存器中,然后将其他参数压栈。
  • __fastcall:为加速调用而生的调用约定,将第一个参数放在ECX中,第二个放在EDX中,然后将后续参数从右至左入栈。

x86 64位调用约定

  • Windows中:依次从左至右将前四个参数放入RCX、RDX、R8、R9这四个寄存器,然后将其余参数从右至左压入栈中。
  • Linux和MacOS:使用RDI、RSI、RDX、RCX、R8、R9这六个寄存器传递前6个参数,其余从右至左入栈。

5.局部变量

局部变量在函数调用时一同临时存储在栈中,每个函数存在的一片栈区域叫做栈帧,一个函数中每个局部变量相对于该函数栈帧的偏移都是固定的,所以引入一个寄存器专门存储栈帧的位置,即EBP。