利用0E820h int 15h 中断获取内存信息********

利用0E820h int 15h 中断获取内存信息

 ; 得到内存数                                 //这段代码是在实模式下写的。

mov ebx, 0
 mov di, _MemChkBuf
.loop:
 mov eax, 0E820h
 mov ecx, 20
 mov edx, 0534D4150h
 int 15h
 jc LABEL_MEM_CHK_FAIL             //如果产生进位,则跳转。 产生进位表示没有成功。 
 add di, 20
 inc dword [_dwMCRNumber]
 cmp ebx, 0                                  //ebx存放的是下一个ARDS的偏移量,第一个是0,如果ebx重新变为0,说明已经到最后一个ARDS了,遍历结束了。
 jne .loop                                     //这样[_dwMCRNumber]就是存放的ARDS的个数。ARDS是地址范围描述符结构,一个ARDS是20个字节。
 jmp LABEL_MEM_CHK_OK
LABEL_MEM_CHK_FAIL:
 mov dword [_dwMCRNumber], 0    //注意这是在实模式下,所以使用的实地址模式。在32位保护模式下就只能使用偏移地址模式。
LABEL_MEM_CHK_OK:                   //_这个符号就表示是实模式下的实地址。

~~~~~~~

------------------------------------------------------------------------------------------------------------------

; 实模式下使用这些符号
; 字符串
_szPMMessage:   db "In Protect Mode now. ^-^", 0Ah, 0Ah, 0 ; 进入保护模式后显示此字符串
_szMemChkTitle:   db "BaseAddrL BaseAddrH LengthLow LengthHigh   Type", 0Ah, 0 ; 进入保护模式后显示此字符串
_szRAMSize   db "RAM size:", 0
_szReturn   db 0Ah, 0
; 变量
_wSPValueInRealMode  dw 0
_dwMCRNumber:   dd 0 ; Memory Check Result
_dwDispPos:   dd (80 * 6 + 0) * 2 ; 屏幕第 6 行, 第 0 列。
_dwMemSize:   dd 0
_ARDStruct:   ; Address Range Descriptor Structure
 _dwBaseAddrLow:  dd 0
 _dwBaseAddrHigh: dd 0
 _dwLengthLow:  dd 0
 _dwLengthHigh:  dd 0
 _dwType:  dd 0

_MemChkBuf: times 256 db 0

; 保护模式下使用这些符号
szPMMessage  equ _szPMMessage - $$
szMemChkTitle  equ _szMemChkTitle - $$
szRAMSize  equ _szRAMSize - $$
szReturn  equ _szReturn - $$
dwDispPos  equ _dwDispPos - $$
dwMemSize  equ _dwMemSize - $$
dwMCRNumber  equ _dwMCRNumber - $$
ARDStruct  equ _ARDStruct - $$
 dwBaseAddrLow equ _dwBaseAddrLow - $$
 dwBaseAddrHigh equ _dwBaseAddrHigh - $$
 dwLengthLow equ _dwLengthLow - $$
 dwLengthHigh equ _dwLengthHigh - $$
 dwType  equ _dwType  - $$
MemChkBuf  equ _MemChkBuf - $$

-------------------------------------------------------------------------------------------------

 32位保护模式下的代码:

 ; 下面显示一个字符串
 push szPMMessage
 call DispStr
 add esp, 4

 push szMemChkTitle
 call DispStr
 add esp, 4

 call DispMemSize  ; 显示内存信息

 call SetupPaging  ; 启动分页机制

 ; 到此停止
 jmp SelectorCode16:0

----------------------------------

DispMemSize:
 push esi
 push edi
 push ecx

 mov esi, MemChkBuf
 mov ecx, [dwMCRNumber] ;        for(int i=0;i<[MCRNumber];i++) // 每次得到一个ARDS(Address Range Descriptor Structure)结构
.loop:     ;                                     {
 mov edx, 5 ;                                    for(int j=0;j<5;j++) // 每次得到一个ARDS中的成员,共5个成员
 mov edi, ARDStruct  ;                         {  // 依次显示:BaseAddrLow,BaseAddrHigh,LengthLow,LengthHigh,Type的数据,并放到一个ARDS中
.1:     ;
 push dword [esi]  ;                                 //注意Dword是32位,就是把esi所指向的32位,4字节数据压入栈
 call DispInt   ;                                        DispInt(MemChkBuf[j*4]); 显示一个成员即分别显示一个ARDS的0,4,8,12,16为起点的4个字节的数据
 pop eax   ;
 stosd    ;                                               ARDStruct[j*4] = MemChkBuf[j*4];
 add esi, 4   ;
 dec edx   ;
 cmp edx, 0   ;
 jnz .1   ;                                              }                            //内循环重复执行五次,依次打印出一个ARDS的5个数据
 call DispReturn  ;                                 printf("\n");              //然后打印换行
 cmp dword [dwType], 1 ;                      if(Type == AddressRangeMemory)   // AddressRangeMemory : 1, AddressRangeReserved : 2
 jne .2   ;                                                 {
 mov eax, [dwBaseAddrLow] ;
 add eax, [dwLengthLow] ;
 cmp eax, [dwMemSize] ;                             if(BaseAddrLow + LengthLow > MemSize)
 jb .2   ;
 mov [dwMemSize], eax ;                             MemSize = BaseAddrLow + LengthLow;
.2:     ;                                                     }
 loop .loop   ;                                 }
     ;
 call DispReturn  ;printf("\n");
 push szRAMSize  ;
 call DispStr   ;printf("RAM size:");
 add esp, 4   ;
     ;
 push dword [dwMemSize] ;
 call DispInt   ;DispInt(MemSize);
 add esp, 4   ;

 pop ecx
 pop edi
 pop esi
 ret

posted on 2011-04-26 22:33  wanghj_dz  阅读(919)  评论(0编辑  收藏  举报

导航