我想打印变量的内存位置(地址):
let x = 1;
println!("{:p}", &x);
Run Code Online (Sandbox Code Playgroud)
这将打印0x7fff51ef6380十进制的十六进制值140734568031104.
我的电脑有16GB的RAM,为什么这么大的数字呢?x64架构是否使用大间隔序列而不是简单的1增量来访问内存位置?
在x86中,通常第一个位置从0开始,然后是1,2,等等.因此,您可以拥有的最高数字大约为40亿,因此地址编号始终等于或小于40亿.
为什么x64不是这种情况?
Luk*_*odt 11
你在这里看到的是虚拟内存的影响.内存管理很难,当操作系统和数百个进程必须共享内存时,内存管理变得更加困难.为了处理这种巨大的复杂性,使用了虚拟内存的概念.我将简要介绍一下这里的基础知识; 这个话题要复杂得多,你也应该把它读到别的地方.
在大多数现代计算机上,每个进程都认为它拥有(几乎)完整的内存空间.但是进程从不处理物理地址,而是处理虚拟地址.每次进程实际从内存中读取时,这些虚拟地址都会映射到物理地址.地址的这种转换由所谓的MMU(存储器管理单元)完成.如何映射地址的规则由操作系统设置.
启动PC时,操作系统会创建初始映射.每次启动进程时,操作系统都会向进程添加几片物理内存,并相应地修改映射.这样,这个过程就有了记忆.
在x86_64上,地址空间为64位宽,因此每个进程都认为它拥有所有这些2 ^ 64个地址.当然,这不是真的:
那么当你尝试读取未映射的地址时会发生什么(在64位的地址中,绝大多数是地址)?MMU触发页面错误.这使CPU通知操作系统处理此问题.
我的意思是在x86中,通常第一个位置从0开始,然后是1,2,等等,所以你可以拥有的最高数字大约是40亿.
这是事实,但如果您的x86系统的RAM少于4GB,也是如此.虚拟内存已存在很长时间了.
这就是为什么你看到这么大的地址的简短摘要.请再次注意,我在这里隐藏了许多细节.
程序使用的指针位于虚拟地址空间中.x86-64使用64位指针.这是AMD64的主要目标之一,同时添加了更多的整数和XMM寄存器.你是对的,i386只有32位指针,每个进程只能覆盖4GB的地址空间.
0x7fff51ef6380 看起来像一个堆栈指针,我猜这个代码是有道理的.
Linux on x86-64(例如)将堆栈置于较低规范地址范围的顶部:当前x86-64硬件仅实现48位虚拟地址,这是防止软件依赖它的机制.这允许将来扩展地址空间而不破坏软件.
系统中的物理RAM量与此无关.你会在x86-64系统上看到(大约)相同的数字,内存为128MB,+/ - 堆栈地址空间布局随机化(ASLR).
| 归档时间: |
|
| 查看次数: |
261 次 |
| 最近记录: |