内存地址是否包含隐式十六进制数字?

Do memory addresses contain implicit hex digits?

在 64 位计算机上,小于 12 个十六进制数字的内存地址的值是多少?

例如,当我在一个简单的汇编程序上 运行 gdb 和 运行 (gdb) info frame 我得到:

Stack level 0, frame at 0x7fffffffd970:
 rip = 0x40052f in main (file.s:11); saved rip = 0x7ffff7a2d830
 source language asm.
 Arglist at 0x7fffffffd960, args: 
 Locals at 0x7fffffffd960, Previous frame's sp is 0x7fffffffd970
 Saved registers:
  rbp at 0x7fffffffd960, rip at 0x7fffffffd968

第二行的第一部分rip = 0x40052f in main (file.s:11)我相信是在我调用info frame时说明了指令指针的值。但是为什么它持有的内存地址不是12位十六进制数呢?

此外,如果我输入 (gdb) x 0x7fffffffd968(我希望是 0x7ffff7a2d830),我会得到:

0x7fffffffd968: 0xf7a2d830

这是否意味着任何少于 12 个十六进制数字的内存地址都包含隐式 7ff...

没有。在 x86 或 x86_64 上,内存地址只是一个数字,但通常使用十六进制显示。和大多数数字表示法系统一样,较短的数字意味着较小的值,或者如果您愿意,它前面有隐含的零。

所以就像十进制字符串“12”远小于“12654321”一样,地址0x40052f也远小于地址0x7ffff7a2d830。这两个地址几乎肯定在不同的虚拟内存映射中。 (在 Linux 上,您可以通过 cat /proc/{pid}/maps 查看虚拟内存映射。)

当您使用 gdb x 命令时,您没有看到预期的值,因为 gdb 猜测您的地址指向的数据类型。第一次在 gdb 会话中使用 x 时,它默认显示每个元素 4 个字节(32 位),就好像地址指向 uint32_t 的数组一样。由于 x86_64 上的地址是 8 个字节(64 位),您需要 x/g 告诉 gdb 元素大小是 8 个字节。