x86-64(AMD64)架构 的寄存器

1. 通用寄存器组:
① RAX(及其子寄存器):rax(64位),eax(32位),ax(16位),ah(8位)
作用:万能通用寄存器,但最固定的用途是存放函数的返回值
② RBX(及其子寄存器):rbx(64位),ebx(32位),bx(16位),bh/bl(8位)
作用:通用数据存储,也常作为被调用者保存寄存器(函数调用时要保护它的值,不被覆盖)
③ RCX:常作为循环计数器(Loop 指令中)
④ RDX:常配合 RAX 做运算
···

2. 栈与指令控制组:
① RIP(程序计数器PC,Program Counter):存放下一条要执行的指令的内存地址
② RSP(栈指针寄存器,Stack Pointer):rsp(64位),esp(32位),用于存放当前栈帧的栈顶地址。
③ RBP(基址指针寄存器,Base Pointer):rbp(64位),ebp(32位),存放当前栈帧的栈底地址。

**数据传送类**

MOV eax, ebx #把 ebx 寄存器里的值复制到 eax 里。
LEA eax, [ebx + 4ecx] #计算 ebx + 4ecx 这个地址,把结果存在 eax 里
PUSH eax #esp = esp - 4(32 位),如果是eax换成rax就是rax=rax-8
POP ebx #把栈顶的值取出来放到 ebx 里

**算术运算类**

ADD eax, 5 #eax = eax + 5
SUB ebx, ecx #ebx = ebx - ecx
CMP eax, ebx #计算 eax - ebx,根据结果存 ZF(零标志)、CF(进位标志),二者均存在别的寄存器
控制转移类

JMP label                 #无条件跳转,直接跳到 label 标记的那行代码继续执行。
JE/JNE/JG/JL label        #有条件跳转,如果前面 CMP 结果相等/不相等/目标>源/目标<源,就跳转到 label
CALL func                 #保存当前位置,然后去执行 func 函数。
地址: 指令

  0x100: mov eax, 1
  0x105: call func    ; 调用函数
  0x10A: add eax, 2   ; ← 返回地址(call的下一条指令)

执行到 0x105 的 call func 时,把下一句指令的地址(0x10A) 压入栈中
,等到执行 ret 指令时,CPU 会自动从栈顶弹出这个地址(0x10A),然后跳回去继续执行。

LEAVE                     #等价于 MOV esp, ebp && POP ebp;用于恢复函数调用前的栈状态。
例子:
   push ebp        ; 保存旧的 ebp
   mov ebp, esp    ; ebp 记录当前栈顶(作为栈底)
   sub esp, 16     ; 分配局部变量空间
   ···
   ···
   leave           ; 相当于:
                   ; mov esp, ebp  → 收回局部变量空间
                   ; pop ebp       → 恢复调用者的 ebp
   ret

ret                       #弹出栈顶的地址,跳回该地址继续执行。这里的pop和leave的pop弹出的值是不一样的

plus:

mov eax, [esp]           #esp是寄存器,里面存的地址作为该寄存器的值,而[]代表访问寄存器的值对应地址的值
举个例子:
    mov eax, esp    把 esp 的值给 eax            esp = 0x1000                          eax = 0x1000
    mov eax, [esp]    把 esp 指向的内存里的值给 eax    esp = 0x1000,内存 0x1000 处存着 123    eax = 123