int 0x15 AX = 0xE820用法

简单来说,每执行一次这个指令将会将一个描述内存区域的数据结构保存到ES:DI,然后返回一个ebx,用于确定下一个能够探测的内存区域,当ebx=0时,表示当前已经时最后一个内存区域了。那么ebx的初始值呢,就是设置成ebx=0。其中可能遇到检查发生错误的情况,这个指令就会直接将CF设置为1。

下图时输入时各个寄存器的作用:

寄存器作用
eax功能码,当输入e820h时能够探测内存
ebx主要用于指向内存区域,第一次调用时ebx=0,被称为continuation value
es:di用于指令执行后,在指向的内存写入描述内存区域的数据结构ARDS(Address Range Descriptor Structure)
ecx用于限制指令填充的ARDS的大小,实际上大多数情况这个是无效的,无论ecx设置为多少,BIOS始终会填充20字节的ARDS
edx0534D4150h(‘SMAP’),输入时在edx,输出时将会在eax中

下面是输出时各个寄存器(标志)的结果:

寄存器结果
CF当没有发生错误时,CF=0,否则CF=1
eax0534D4150h(‘SMAP’)
ebx指向下一个内存区域,而不是调用之前的内存区域,当ebx=0且CF=0时,表示当前是最后一个内存区域。
es:di和调用之前一样,如果要保存多个ARDS,需要手动修改es:di
ecx返回写入的ARDS的大小

ARDS的结构(共20字节,Type为4字节)

偏移名称意义
0BaseAddrLow基地址的低32位
4BaseAddrHigh基地址的高32位
8LengthLow长度(字节)的低32位
12LengthHigh长度(字节)的高32位
16Type这个内存区域的类型

ARDS的Type取值如下:

取值名称意义
1AddressRangeMemory可以被OS使用的内存
2AddressRangeReserved正在使用的区域或者不能系统保留不能使用的区域
其他未定义各个具体机器会有不同的意义,在这里我们暂时不用关心,将它视为AddressRangeReserved即可

(好像csdn的汇编代码块高亮用不了,就只能这样了)

;当前处于实模式
_MemChkBuf: times 256 db 0
_dwMCRNumber: dw 0   ;记录ARDS的数量
...
	mov ebx,0
	mov di,_MemChkBuf ;请忽略es,假设已经正确设置好了
.loop:
	mov eax,0e820h
	mov ecx,20
	mov edx,0534D4150h ;'SMAP'
	int 15h
	jc LABEL_MEM_CHK_FAIL ;检查CF,是否发生错误
	add di,20	;由于执行INT 15h之后es和di不发生改变,就需要手动修改
	inc dword [_dwMCRNumber] ;记录ARDS的数量
	cmp ebx,0;判断是否到达最后一个内存区域
	jne .loop
	jmp LABEL_MEM_CHK_OK ;ebx=0到达最后一个内存区域
LABEL_MEM_CHK_FAIL:
	mov dword [_dwMCRNumber],0
LABEL_MEM_CHK_OK:

如果要读取就从开始es:di开始的地方开始逐个读取内存区域,得到的结果和这个类似

]

当然Linux上也有e820都差不多

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值