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...
?
答案 0 :(得分:1)
没有。在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个字节。