寄存器是 CPU 内部的一小块高速存储,容量极小但读写几乎不耗时间。运算、传参、存返回值、记下一条指令地址,都要先经过它;调试和逆向时盯住寄存器,基本就能知道程序此刻在干什么。x86-64 上常见的几个:rax 放返回值,rdi、rsi、rdx 依次传前几个整数参数,rsp 指栈顶,rbp 指栈帧底,rip 指下一条要执行的指令。
用法就一句话:把程序丢进调试器,断点停下后直接打印寄存器,需要看数据时再按寄存器里的地址读内存。
最小示例:
gcc -g -O0 demo.c -o demo # 带调试信息编译,-O0 关优化,寄存器才和源码对得上
gdb ./demo # 启动调试器
# 进入 gdb 后依次输入:
# break main # 在 main 下断点
# run # 跑起来,停在断点
# info registers rip rsp rbp # 查看关键寄存器
# x/4i $rip # 从 rip 开始反汇编 4 条指令
新手最容易踩的两个坑。一是编译时开了优化,变量被塞进寄存器甚至直接优化掉,调试器里打印变量会提示 optimized out,别以为调试器坏了,看寄存器本身就行。二是 rax、eax、ax、al 是同一个寄存器的不同宽度视图,写 eax 会把高 32 位清零,写 al 只动最低 8 位,读的时候别把它们当成四个独立变量。