linux 文件400,linux – 为什么地址0x400000被选作x86_64 ABI中的文本段的开始?

底线:amd64在使用大地址方面的一些技术限制建议将地址空间的较低2GiB专用于代码和数据以提高效率。因此,堆叠已重新定位在此范围之外。

> stack位于代码之前,从0x8048000向下增长。其中提供“有点超过128 MB

对于堆栈和大约2 GB的文本和数据“(第3-22页)。

>动态段从0x80000000(2GiB)开始,

>并且内核占据顶部的“保留区域”,该规范允许高达1GiB,从至少0xC0000000(p。3-21)(which is what it typically does)开始。

>主程序不需要与位置无关。

>一个实现不需要捕获空指针访问(p。3-21),但是合理的是期望高于128MiB(即288KiB)的一些栈空间将被保留用于该目的。

amd64(whose ABI被修改为i386的一个(第9页))具有非常大的(48位)地址空间,但大多数指令只接受32位立即操作数(其中包括跳转指令中的直接地址和偏移量) ,需要更多的工作和更低效率的代码(特别是当考虑指令相互依赖性)来处理更大的值。作者通过介绍一些他们建议使用的“允许编译器生成更好的代码”的“代码模型”来总结解决这些限制的措施。 (第33页)

>具体来说,第一个“小代码模型”建议使用“从0到231-224-1或从0x00000000到0x7effffff”范围内的地址,这允许一些非常有效的相对引用和数组迭代。这是1.98GiB这是足够的许多程序。

>“中代码模型”基于前一个,将数据分割为上述边界下的“快”部分和需要特殊指令访问的“较慢”剩余部分。虽然代码仍然在边界下。

>只有“大”模型不对大小做出假设,要求编译器“使用movabs指令,如在介质中

代码模型,甚至用于处理文本段内的地址。此外,当分支到地址时需要间接分支

偏离当前指令指针是未知的“。他们继续建议将代码库拆分为多个共享库,因为这些措施不适用于已知在边界内的偏移的相对引用(如”小位置无关代码模型”)。

因此,栈被移动到共享库空间(0x80000000000,128GiB)下,因为它的地址从不是立即操作数,总是间接地或者从另一个引用的lea / mov引用,因此只有相对偏移限制适用。

上面解释了为什么加载地址被移动到较低的地址。现在,为什么它被移动到正好0x400000(4MiB)?在这里,我是空的,所以,总结我在ABI规范中阅读,我只能猜到它感觉“恰到好处”:

>它足够大以捕获任何可能不正确的结构偏移,允许amd64操作的更大的数据单元,但足够小,不会浪费大量的有价值的起始2GiB的地址空间。

>它等于到目前为止最大的实际页面大小,是所有其他虚拟内存单元大小的倍数。

1注意,随着时间的推移,实际的x32 Linuxes已经偏离了这种布局more和more。但是我们在这里谈论ABI规范,因为amd64正式基于它,而不是任何派生的布局(参见其引用的段落)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值