计算机微刊

探测内存

2019-03-21  本文已影响0人  HAPPYers

本文介绍三种探测内存的方法
探测内存是通过调用 BIOS 中断 0x15 实现的
分别 是 BIOS 中断 0x15 的 3 个子功能

一、利用 BIOS 中断 Ox15 子功能 0xE820 获取内存

INT15h BIOS 中断的详细调用参数:
eax:e820h:INT 15 的中断调用参数;
edx:534D4150h (即 4 个 ASCII 字符―SMAP‖) ,这只是一个签名而已;
ebx:如果是第一次调用或内存区域扫描完毕,则为 0。 如果不是,则存放上次调用之后的计数值;
ecx:保存地址范围描述符的内存大小,应该大于等于 20 字节;
es:di:指向保存地址范围描述符结构的缓冲区,BIOS 把信息写入这个结构的起始地址。
此中断的返回值为:
cflags 的 CF 位:若 INT 15 中断执行成功,则不置位,否则置位;
eax:534D4150h ('SMAP') ;
es:di:指向保存地址范围描述符的缓冲区,此时缓冲区内的数据已由 BIOS 填写完毕
ebx:下一个地址范围描述符的计数地址
ecx :返回 BIOS 往 ES:DI 处写的地址范围描述符的字节大小
ah:失败时保存出错代码



通过调用 INT 15h BIOS 中断,递增 di 的值(20 的倍数),让 BIOS 帮我们查找出一个一个的内存布局 entry,并放入到一个 保存 地址范围描述符(见文章 INTEL基础结构) 结构的缓冲区中,供后续使用.

ARDS地址范围描述符
struct e820map {
int nr_map;
struct {
long long addr;
long long size;
long type;
} map[E820MAX];
};
probe_memory:
    movl $0, 0x8000
    xorl %ebx, %ebx
    movw $0x8004, %di
start_probe:
    movl $0xE820, %eax
    movl $20, %ecx
    movl $SMAP, %edx
    int $0x15
    jnc cont
    movw $12345, 0x8000
    jmp finish_probe
cont:
    addw $20, %di
    incl 0x8000
    cmpl $0, %ebx
    jnz start_probe
finish_probe:

二、利用 BIOS 中断0x15 子功能 0xE801 获取内存



三、利用 BIOS 中断 0x15 子功能 0x88 获取内存

最后一个获取内存的方法也同样是 BIOS 0x15 中断,子功能号是 0x88。
该方法使用最简单,但功能也最简单,简单到只能识别最大 64MB的内存。即使内存容量大于 64MB,也只会显示 63MB。因为此中断只会显示 1MB 之上的内存,不包括1MB。在使用的时候记得加上 1M.



上一篇 下一篇

猜你喜欢

热点阅读