有时候你可能会有这样的疑惑:为什么页面大小是4K,而VirtualAlloc函数分配的内存是以64K(而不是4K)为边界呢?

事情还得从Alpha AXP处理器说起

在Alpha AXP处理器上,没有一条指令对应”加载一个32位的证书”这样的操作,取而代之地,实际上是加载两个16位的整数然后将它们合并成32位的。

所以,如果内存分配粒度小于64K,则一个需要重新定位的DLL将会需要对每一次重新分配的地址做出两次调整:一次是高16位地址,另一次是低16位地址。如果这改变了两半地址之间的进位或借位,情况就会变得更糟。(例如,将4K的数据从0x1234F000移到0x12350000,这将迫使地址的低16位和高15位都发生改变。即使移动的地址量远小于64K,但由于存在进位,这项操作仍然对地址的高16位部分产生影响)

除了这个,还有更糟的

Alpha AXP处理器实际上会合并两个16位的带符号整数到一个32位的整数。例如,为了加载0x1234ABCD,你需要首先使用LDAH指令加载0x1234到目标寄存器的高16位,然后再使用LDA指令加上带符号整数-0x5433(因为,0x5433 = 0x10000 – 0xABCD),才能得到预期的结果0x1234ABCD。

因此,如果重定位导致地址在64K块的”下半部分”和”上半部分”之间移动,则必须进行其他修正,以确保正确调整了地址上半部分的算法。由于编译器喜欢对指令进行重新排序,因此该LDAH指令可能距离很远,因此下半部分的重定位记录将不得不采用某种方式来找到匹配的上半部分。

而且,编译器很聪明,如果需要为同一64K区域中的两个变量计算地址,则它们之间共享LDAH指令。如果可以通过不是64K的倍数的值进行重定位,则编译器将不再能够执行此优化,因为在重定位之后,这两个变量不再属于同一64K内存块中。

强制以64K粒度分配内存可解决所有这些问题。

如果你仔细观察的话,你会发现这也解释了为什么2GB边界附近有64K的”无人区”。考虑一下计算值0x7FFFABCD的方法:由于低16位在64K范围内,该值需要通过减法而不是加法来计算。一种比较想当然的解决方案:

上面的做法行不通

Alpha AXP是64位处理器,0x8000不适合放入到16位带符号整数中,因此必须使用-0x8000(负数)。所以,实际发生的是:

你需要添加第三条指令来清除高32位。一种巧妙的技巧是,将零加起来,然后告诉处理器将结果视为32位整数并将其符号扩展为64位。

如果允许访问2GB边界的64K范围内的地址,则每一次内存地址计算都必须插入上面所提到的第三条ADDL指令,以防万一该地址被重新分配到2GB边界附近的“危险区域”。

要访问地址空间中的最后一个64K区域,会付出一笔非常高的代价:对于所有地址计算,其性能都会受到50%的影响,以避免在实践中永远不会发生这种情况。因此,将这片区域设置为永久禁用,是一种更为明智的选择。

lp地址为什么位_为什么内存空间分配总是以64K为边界?相关推荐

  1. 内存地址、位宽与容量

    首先说明一下单位: 1K=2^10,1M=2 ^20: 1MB=1M Byte=2^20 Byte =8 * 2 ^20 bit: 1Mb=1M bit=2^20 bit: 存储容量=寻址范围 x 计 ...

  2. 32位下的内存地址分布

    32位下的内存地址分布图如下:1g为内核空间,3g为用户空间 内核空间:内核空间表示运行在处理器最高级别的超级用户模式(supervisor mode)下的代码或数据,内核空间占用从0xC000000 ...

  3. C/C++学习之路_七: 内存管理

    C/C++学习之路_七: 内存管理 目录 作用域 内存布局 内存分区代码分析 1. 作用域 C语言变量的作用域分为: 代码块作用域(代码块是{}之间的一段代码) 函数作用域 文件作用域 1. 局部变量 ...

  4. 707-详解32位Linux系统内存地址映射

    详解32位Linux系统内存地址映射 我们先看一段简单的C程序: 我们先来看一张图: 我们平时所说的x86 32位指的是:80386往后到现在的同一个体系的CPU处理芯片,但是x86这个芯片是从808 ...

  5. 物理内存是什么是计算机的显卡内存吗,物理内存可用数_可用内存和物理内存是什么意思?_可用物理内存...

    网友求助:物理内存可用数_可用内存和物理内存是什么意思?_可用物理内存 问题 最佳答案 物理内存:电脑主板上插入的内存条的总容量(在系统支持的范围内).可用内存:电脑运行时,未被使用的内存总量. 追问 ...

  6. 易语言64位端游内存封包逆向教程介绍---传奇4实战(易全网首套)

    易语言是否支持64位游戏内存或者注入呢?当然是支持的.下面内容教大家如何用易语言 写内存和封包辅助. 技术声明:本教程只能用于计算机技术研究,不做其他用途,如果有疑问,可以联系我. 复习位内存汇编基础 ...

  7. 动态创建数组了解各种取值和取地址的问题以及感受内存地址

    image.png 源代码: #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include "cd.h"//严重 ...

  8. 4g内存只有1.6g可用_32位系统可用内存小 遇到32位系统内存小的解决方法

    内存是CPU进行沟通的桥梁,我们计算机上所有的程序都是在内存中运行的,如果内存不够用,可能系统缓慢卡顿,甚至会造成系统崩溃.那今天小编就给大家介绍一下32位系统可用内存小的解决方法,感兴趣的小伙伴一起 ...

  9. c语言相邻地址相差多少,C语言内存地址基础

    从计算机内存的角度思考C语言中的一切东东,是挺有帮助的.我们可以把计算机内存想象成一个字节数组,内存中每一个地址表示 1 字节.比方说我们的电脑有 4K 内存,那这个内存数组将会有 4096 个元素. ...

最新文章

  1. Celery--任务调度利器
  2. 【青少年编程】陈晓光:打靶游戏
  3. go 指针变量和普通变量的转化_C语言 | 指向结构体变量的指针变量
  4. 编译gtk+程序报错gcc: pkg-config --cflags --libs gtk+-2.0: 没有那个文件或目录
  5. Sqoop_ 简单介绍
  6. 网络流题目详讲+题单(提高版)(持续更新中......)
  7. c++ 单例模式_Java面试题总结之设计模式、网络基础、常用算法
  8. Entity Framework 批量插入
  9. Linux unit14
  10. 想接私活收入翻倍,建议根据这几个开源SpringBoot项目(含小程序)改改~
  11. office 兼容包下载地址
  12. Android视频播放器
  13. 简单6步,手把手搭建MinDoc文档库
  14. 形容等待时间长的句子_形容等待的句子
  15. get、put、post、delete四大请求的含义与区别个人理解和解释
  16. Java解P2678 [NOIP2015 提高组] 跳石头,有图有注释,通俗易懂
  17. 关于CSS与HTML知识点总结(一)
  18. 企业抖音蓝v怎么认证?详谈蓝v申请认证流程
  19. Actor模式理解与使用
  20. parameterMap与parameterClass

热门文章

  1. linux镜像默认的安装位置,Linux下正确修改Docker镜像和容器的默认存储位置,亲测有效...
  2. 阿里云数据库再添新成员,企业级MariaDB正式开卖!
  3. ant-mobile的Toast的样式修改(react)
  4. 如何防止网站被SQL注入攻击之java网站安全部署
  5. 开发者应该关注的五项Web新兴技术:WebGL和SVG名列其中
  6. 在制作只有一页的WORD小报时再添加一页
  7. jQuery自己定义绑定的魔法升级版
  8. eclipse代码自动提示,eclipse设置代码自动提示
  9. 流程控制语句【循环、条件】
  10. 华为机试HJ17:坐标移动