寄存器值本身仅为数值,需结合x命令解引用查看内存内容:x/wx $rax读4字节,x/gx $rax读8字节,x/s $rax读字符串;无效地址会报“Cannot access memory at address”,配合info proc mappings可判断地址所属内存区域。

用 print 或 x 查寄存器值本身
寄存器里存的只是数值,比如 $rax 是 0x7fffffffe280,它本身不“指向哪里”,只是个地址。要确认这个值是否有效、指向什么内容,得先把它当地址用。
- 直接打印寄存器值:
print $rax(默认按寄存器类型推断格式) - 强制十六进制显示:
print/x $rax - 如果寄存器存的是指针,
print <em>(int</em>)$rax可解引用看它指向的 int 值(注意类型匹配,否则会读错字节数)
用 x 命令查看该地址处的内存内容
x 是专门干这事的:把寄存器值当作内存地址去读。
- 查 4 字节(一个 int):
x/wx $rax - 查 8 字节(x86_64 下一个指针):
x/gx $rax - 查 16 字节并按字符显示:
x/16cb $rax - 查字符串(自动停在 \0):
x/s $rax
常见错误:
- 忘记加
$:写成x/s rax会报错,必须是$rax - 地址无效时 gdb 报
Cannot access memory at address 0x...,说明寄存器值是野指针、已释放内存或未初始化
结合 info registers 和 info proc mappings 判断地址归属
光看值和内容还不够,得知道这个地址落在哪块内存区域。
-
info registers看所有通用寄存器当前值 -
info proc mappings显示进程的内存布局(需 Linux + /proc 支持),能告诉你0x7fffffffe280属于[stack],而0x555555559000很可能在.text或.data段 - 如果地址落在
[heap]区间,大概率是 malloc 分配的;在[stack]就是局部变量或参数;在[vdso]或[vvar]则是内核映射,不能随便读
小心指针层级和符号信息缺失
- 如果寄存器存的是二级指针(如**pp),x/gx $rax 只能看到一级地址,得再套一次:x/gx *(long*)$rax
- 没带 -g 编译时,print 可能无法还原变量名,但 x 仍可用——它不依赖调试信息,只认地址和字节
- x/i $rip 这类指令查看要慎用:如果寄存器值不是合法代码地址,gdb 会报错或显示乱码,不代表崩溃,只是当前上下文不适用
真正容易被忽略的点是:寄存器值是否对齐、是否受 ASLR 影响、是否在当前栈帧生命周期内有效。比如函数返回后还去读 $rbp 指向的旧栈帧,内容可能已被覆盖,看到的“地址”依然能读,但语义已失效。


















