微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

需要了解0x7fffffff和0xffffffff80000000在内存地址空间布局方面的含义

如何解决需要了解0x7fffffff和0xffffffff80000000在内存地址空间布局方面的含义

# 0x00007f33caf5a85f: cmp rax,0xffffffff80000000
# 0x00007f33caf5a865: jnl 0x7f33caf5a898
...
target_of_jnl:
# 0x00007f33caf5a898: cmp rax,0x7fffffff
# 0x00007f33caf5a89e: jle 0x7f33caf5a8c8

上面的代码片段是libstdc ++中函数_M_extract_int()的执行流的一部分。

我不明白两个比较的含义。我认为0xffffffff80000000是可用于用户模式的顶级物理内存地址。但是0x7fffffff呢?他们在检查什么?

解决方法

请注意,0x...8650x...898不是连续的,即使它们在问题中显示为一个连续块的一部分,没有空行。一个是另一个的分支目标。

似乎正在检查的值是否适合32位2的补码整数,即INT32_MIN和INT32_MAX(含)之间。像x == (int32_t)x

但是分支对象的上半部分和下半部分不同,否则可以简单地movsxd rdx,eax / cmp rax,rdx / je

jnl is the same condition as jge,所以它在(int64_t)rax >= INT_MIN上跳跃,而INT_MIN当然会扩展为64位。

   cmp rax,0xffffffff80000000                   # INT32_MIN
   jge   x_ge_INT32_MIN
# else fall-through: x < INT32_MIN
  ... other code here

x_ge_INT32_MIN:
   cmp rax,0x7fffffff                           # INT32_MAX
   jle   x_fits_in_int32_t

  ... else it doesn't,x > INT32_MAX

请注意,0xffffffff80000000代表一个负号整数(int64_t)INT32_MIN。这是32位0x80000000的符号扩展。


我不知道_M_extract_int()是做什么的,并且您没有链接任何libstdc ++源的使用信息。


我认为0xffffffff80000000是可用于用户模式的顶部物理内存地址

否,0xffffffff80000000位于虚拟地址空间的上半部分,因此还不太高。有关x86-64 48位规范化虚拟地址空间的图表,请参见Address canonical form and pointer arithmetic

Linux(我认为所有主流的x86-64操作系统)都保留了整个上半部分供内核使用,而用户空间可以在下半部分分配/映射页面。即用户空间可以使用虚拟地址空间的整个低47位。 (也许不是最底层,例如,Linux默认情况下会停止映射低64k的进程,因此nullptr取消引用,即使有偏移量也仍然会出错。MacOS会保留整个低4GiB。)

通过5级页表(Intel的PML5扩展),用户空间可以使用57位虚拟地址空间的低56位。

无论哪种方式,这都与该代码所寻找的内容相似,但具有48或57位的值正确地符号扩展为64位而不是32位。

物理

不。 libstdc ++仅在用户空间中使用,因此它只能看到的唯一地址是虚拟的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。