转载自:https://blog.csdn.net/sinolover/article/details/93886204
咱们先介绍0xE820子功能,这是最灵活的内存获取方式。
bios中断 0x15的子功能0xE820能够获取系统的内存布局,由于系统内存各部分的类型属性不同,bios就按照类型属性来划分这片系统内存,所以这种查询则呈迭代式,每次bios只返回一种类型的内存信息,直到将所有内存类型返回完毕。子功能0xE820的强大之处是返回的内存信息较丰富,包括多个属性字段,所以需要一种格式结构来组织这些数据。内存信息的内容是用地址范围描述符来描述的,用于存储这种描述符的结构称之为地址范围描述符ARDS,Address Range Descriptor Structure。见格式见表
此结构中的字段大小都是4字节,共5个字段,所以此结构大小为20字节。每次int 0x15之后,bios就返回这样一个结构的数据。注意,ARDS结构中是用64位宽度的属性来描述这段内存基地址(起始地址)及其长度,所以表中的基地址和长度都分为低32位和高32位两部分。
其中的Type字段是用来描述这段内存的类型,这里所谓的类型是说明这段内存的用途,是可以被操作系统使用,还是保留起来不能用。Type字段的具体意义见表
为什么bios会按类型来返回内存信息呢?原因是这段内存可能是:
- 系统的ROM。
- ROM用到了这部分内存。
- 设备内存映射到了这部分内存。
- 由于某种原因,这段内存不适合标准设备使用。
由于我们是在32位环境下工作,所以在ARDS结构属性中,我们只用到低32位属性。BaseAddrLow+LengthLow是一片内存区域上限,单位是字节。正常情况下,不会出现较大的内存区域不可用的情况,除非安装的物理内存极其的小。这意味着,在所有返回的ARDS结构里,此值最大的内存块一定是操作系统可使用的部分,即主板上配置的物理内存容量。
bios中断只是一段函数例程,调用它就要为其提供参数,现在介绍下bios中断0x15的0xe820子功能需要哪些参数。
先介绍下此中断例程的调用方法。下表是使用此中断的方法,分输入和输出两部分。
表中的ECX寄存器和ES:DI寄存器,是典型的“值-结果”型参数,即调用方提供了两个变量做为被调用函数的参数,一个变量是缓冲区指针,另一个变量是缓冲区大小。被调用函数在缓冲区中写入数据后,将实际所写入的字节数记录到缓冲区大小变量中。
根据上表中的说明,此中断的调用步骤是:
- 填写好“调用前输入”中列出的寄存器。
- 执行中断调用int 0x15。
- 在CF位为0的情况下,“返回后输出”中对应的寄存器便会有对应的结果。
欢迎关注我的公众号“灯珑”,让我们一起了解更多的事物~