31-32 - 获取物理内存容量

文章详细介绍了BIOS提供的内存相关中断int0x15的两种功能,用于检测和获取物理内存容量。基础功能(int0x15:E801)用于获取15MB以下和16MB以上内存信息,而进阶功能(int0x15:E820)配合ARDS结构体能获取更详细的内存范围信息。文章通过汇编小贴士、编程实验和问题解答,帮助读者理解如何利用这些中断获取系统内存大小。
摘要由CSDN通过智能技术生成

---- 整理自狄泰软件唐佐林老师课程

查看所有文章链接:(更新中)深入浅出操作系统 - 目录

1. 讨论

  • 怎么知道还剩多少空闲页框?一共有多少页框可用?
    ==> 如何获取系统物理内存的大小?

2. BIOS提供的内存相关中断(int 0x15)

  • 基础功能(eax = 0xE801)
    • 分别检测低15MB和高16MB~4GB的内存
    • 最大支持4GB内存检测
  • 高级功能(eax = 0xE820)
    • 遍历主机上所有的内存
    • 获取各个内存范围的详细信息

2.1 int 0x15基础功能

  • 中断参数
    eax = 0xE801
  • 返回值:
    • cf = 0 ==> 成功0,出错1
    • ax、cx ==> 以1KB为单位,表示15MB以下的内存容量
    • bx、dx ==> 以64KB位单位,表示16MB以上的内存容量
    • (少了1MB,下面的内容会讲到)

2.1.1 汇编小贴士

在这里插入图片描述
在这里插入图片描述
注:有进位就跳转到标签处。

  • 进位标志位
    • 判断运算过程是否进位/借位
    • 运算不需要进位/借位时CF位的值为0,否则为1

2.1.2 int 0x15基础功能示例

在这里插入图片描述
在这里插入图片描述

2.1.3 编程实验:获取物理内存容量

【参看链接】:31-32 - 获取物理内存容量 / 31 / 00

因为要使用bios中断,故在16位code中添加GetMemSize
反编译不加:-b 32
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.1.4 问题

  • 为什么0xE801获取的内存容量分两部分表示?
  • 为什么0xE801获取的内存容量少了1MB?
  • 一些历史原因
    • 80286中的24根地址线最大寻址范围是16MB
    • 当时的ISA设备使用15MB以上的地址作为缓冲区
      • 操作系统无法使用15MB~16MB的物理内存
      • 80386之后的处理器为了兼容,多余16MB的内存容量单独返回

在这里插入图片描述

  • 为了兼容性,在使用int 0x15后,ax寄存器最多表示15MB的内存容量,即:最大值为0x3C00,这样,对于80286时代的各种程序就可以完全兼容,正常执行。

2.1.5 修正物理内存容量

在这里插入图片描述

【参看链接】:31-32 - 获取物理内存容量 / 31 / 01

在这里插入图片描述
在这里插入图片描述

2.1.6 小推论

  • eax = 0xE801 所返回的是可实际使用的内存容量
  • 处理器对内存地址空间做了分段处理(这里的分段不是保护模式下的分段,而是处理器对内存地址空间的分段)
  • 问题
  • 是否能够获取处理器对内存地址进行分段的详细信息?

2.2 int 0x15进阶版功能

  • 高级功能(eax = 0xE820)
    • 遍历主机上所有的内存
    • 获取各个内存范围的详细信息
  • 中断参数

eax = 0xE820(固定值)
edx = 0x534D4150(固定值)
ebx ==> 初始参数必须为0,终止标志
ecx ==> ARDS结构体大小(20字节)
es:di ==> ARDS结构体数组(每个元素占用20字节)

2.2.1 地址范围描述结构(Address Range Descriptor Structure)

在这里插入图片描述

2.2.2 int 0x15进阶功能示例

伪代码:
在这里插入图片描述

2.2.3 编程实验:获取ARDS记录

【参看链接】:31-32 - 获取物理内存容量 / 32 / 00

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2.4 问题

  • ARDS记录中并没有包含物理内存容量的信息,那么记录这些记录有什么意义?

2.2.5 ARDS结构体中的Type成员

  • type = 1:AddressRangeMemory
    这段内存可以被操作系统使用
  • type = 2:AddressRangeReserved
    内存使用中或被保留,操作系统不可使用
  • type = 其它值:未定义
    保留,可当作AddressRangeMemory处理

2.2.6 根据ARDS记录来计算物理内存

在这里插入图片描述

  • 在32位系统中:
    • ARDS结构体中的 BaseAddrHigh 和 LengthHigh 均为 0(32位系统中只需要关心32位的BaseAddrLow)
    • 物理内存容量需要通过属性为1的内存段计算
    • 计算方式为:max { BaseAddrLow + LengthLow }
      • BaseAddrLow + LengthLow 是一段内存的地址上限
        (当一片内存可被操作系统使用,且地址上限最大时,这个地址上限就是物理内存的大小)
  • 伪代码

在这里插入图片描述

【参看链接】:31-32 - 获取物理内存容量 / 32 / 01

这里借用上述实验的图片,计算出 属性为 1 的内存段大小等于0x01ff0000并不等于32MB,算上属性为3的长度0x10000,0x01ff0000+0x00010000=0x02000000=32MB(暂时不清楚为啥属性3的要加上)。
在这里插入图片描述

  • 实验中使用的策略:
  1. 通过0xE801计算物理内存的大小
  2. 通过0xE820获取各个ARDS并填入结构体数组
  3. 根据ARDS结构体数组计算物理内存的大小
  4. 选择通过0xE801和0xE820计算得到的较大内存容量作为最终结果
    在这里插入图片描述

在这里插入图片描述

  • Linux中获取物理内存容量的策略

在这里插入图片描述

3. 小结

  • int 0x15可用于获取物理内存容量
  • 0xE801子功能修正后可得到物理内存容量
  • 0xE820子功能通过ARDS得到更详细的内存信息
  • 需要多次使用0xE820子功能才能获得物理内存容量
  • 操作系统依赖于BIOS中断获取硬件信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

uuxiang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值