跳转到内容

认识汇编 - 寄存器

寄存器

通用寄存器

常规使用的寄存器
RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, R8, R9, R10, R11, R12, R12, R13, R14, R15
其中RSP始终指向stack顶部的位址,在C编译风格的程式RBP指向局部变量顶部的位置
还有一个特殊的寄存器RIP始终指向下一条要执行的指令,也就是我们学过的程序计数器
RIP在使用者端不可写(read only)

寄存器长度

64 32 16 8 8
RAX, EAX, AX, AH, AL

AL是最右边8位,AH是接着8位,AH和AL合起来是AX
在nasm语法中,取用寄存器大小直接依照上述写法即可
后面的寄存器如下:

rsi, esi, si, sil
rdi, edi, di, dil
rsp, esp, sp, spl
r8, r8d, r8w, r8b

寄存器用途

列举了一些通用寄存器的常见用途

  • rax: 存放函数的返回值
  • rcx: 循环的迭代变量(while i--)i
  • rdx: 当两个寄存器合并使用成16位时,左边8位的内容
  • rsi: 来源内容
  • rdi: 目的内容
  • rbp: 局部变量顶部
  • rsp: stack顶部 (规定)

函数呼叫规范

呼叫函数时需要将参数内容放入对应的寄存器
linux使用的顺序为:
rdi, rsi, rdx, rcx, r8, r9, rsp(栈)
windows使用的顺序为:
rcx, rdx, r8, r9, rsp(栈)

rdi rsi rdx
f(arg1, arg2, arg3)

假设要呼叫一个函数f,参数需要先放入对应的地方,函数进入后会当作已经将参数放好了直接使用
超过的长度则全部放入堆叠中

浮点寄存器

处理浮点数的寄存器

XMM0 ~ XMM15 128位
YMM0 ~ YMM15 256位
ZMM0 ~ ZMM15 512位

另外还有ST0~ST7只能存放纯浮点数已逐渐被淘汰

标志寄存器

包含特定的状态标志,有些指令运行过程会使用并依照情况亮灯
比如常用的ZF,当ZF亮了表示值为0,像是加减法和cmp都会触发
举个例子:

while(n--) {}

我们只要一直执行dec递减1,使用jz 当ZF触发则跳转到另一个地方
但不是所有指令出现0都会ZF,常用的xor就不会触发,这部份请查找网络资料和Intel x86_64指令集文档
还有CF(进位)、SF(符号)、OF(溢位)、DF(方向)等

段寄存器

CS、DS、SS、ES、FS、GS
这些一般隐式出现,但有两个以前常用的
看到ds:si意思为rsi寄存器加上ds
看到es:di意思为rdi寄存器加上es
以前16位元使用rep指令重复时,ds和es就像循环递增的迭代变量(i)一样的概念
现在几乎弃用