x命令用于直接查看内存原始内容,不依赖符号表,格式为x/n[u] address,其中n为单元数量、f为显示格式(如x十六进制、s字符串)、u为单元大小(如b字节、w字),地址可为&var、$rsp或具体数值。

用 x 命令查看内存,不是 print
print(或 p)只看变量值,依赖符号表和类型信息;而真正查“原始内存”的是 x(examine 的缩写)。比如你怀疑指针越界、结构体对齐异常、或想确认字符串是否以 \0 结尾,必须用 x。
-
x不关心变量名,只认地址:可以是&var、$rsp、0x7fffffffe000,甚至memory + 8 - 它不解析类型,直接按你指定的格式和单位读内存
- 错误常见于把
print当万能命令,结果看到的是“解释后”的值,不是内存里真实存的字节
x/4xw &buf 这类写法中,每个字母代表什么
x/[n][f][u] address 是唯一可靠语法,顺序不能乱,参数含义明确:
-
n(数量):要显示的“单元”个数,不是字节数。例如/8表示 8 个单元,每个单元大小由u决定 -
f(格式):控制怎么“解释”这些单元。常用:x(十六进制)、d(有符号十进制)、u(无符号十进制)、c(字符)、s(字符串)、i(汇编指令) -
u(单位):每个单元占多少字节:b(1 字节)、h(2 字节)、w(4 字节,默认)、g(8 字节)
举几个典型组合:
-
x/16xb &data:从&data开始,连续显示 16 个字节,每个字节用十六进制表示 -
x/5dw &arr:把&arr当作一个整型数组首地址,显示前 5 个int(假设是 4 字节),用有符号十进制 -
x/s str:从str指向的地址开始,按 C 字符串规则打印(遇到\0停止)
容易踩的坑:单位和格式混用、回车重复行为被忽略
- 把w(word,4 字节)当成“显示 4 字节”,其实是“显示 1 个单元,每个单元 4 字节”。所以 x/4w &a 实际读 16 字节,不是 4 字节
- x/4x &a 缺少单位时默认用 w,等价于 x/4xw &a,但新手常误以为是“4 字节”
- 执行一次 x/8xb &buf 后,直接按回车会从 &buf + 8 继续显示下 8 字节——这个“地址自动递进”特性很实用,但也容易误判起始位置
- x/s 和 x/c 看似都跟字符有关,但 x/s 会一直读到 \0,x/10cb 则严格只读 10 个字节并转成字符,哪怕中间有 \0 也不停
调试时该选哪个格式和单位
选法取决于你要验证什么:- 查栈帧或寄存器变化:用
x/16xb $rsp(字节级观察,避免单位过大跳过关键偏移) - 看函数调用前后的参数传递:用
x/6xw $rsp(x86_64 下前 6 个参数可能在寄存器,但栈上仍有返回地址、保存寄存器等,4 字节单位更通用) - 分析浮点数内存布局:
x/fw &f显示单精度,x/gx &d显示双精度的 8 字节原始位模式 - 验证字符串是否截断或溢出:
x/32cb &str强制显示 32 个字节的字符,比x/s更可靠(后者遇\0就停,可能掩盖越界写入)
真正难的不是记住所有组合,而是每次执行 x 前,心里清楚:我要看的是“谁的地址”、“打算按什么粒度切”、“希望它被怎么解释”。漏掉任意一环,看到的就只是错觉。


















