(第三章 13)克勤克俭用内存——查看内存块
?
[SECTION .data1]
ALIGN32
[BITS32]
_MemChkBuf:times256db0 ? ? ? ? ? ? ? ?;20bytes的ARDS可以放12个
MemChkBufequ_MemChkBuf- $$
?
_dwMCRNumber:dd0; Memory Check Result ?--> ?放置ARDS结构数组的结构元素个数
dwMCRNumberequ_dwMCRNumber- $$
?
_ARDStruct:; Address Range Descriptor Structure
_dwBaseAddrLow:dd0
_dwBaseAddrHigh:dd0
_dwLengthLow:dd0
_dwLengthHigh:dd0
_dwType:dd0
ARDStructequ_ARDStruct- $$
dwBaseAddrLowequ_dwBaseAddrLow- $$
dwBaseAddrHighequ_dwBaseAddrHigh- $$
dwLengthLowequ_dwLengthLow- $$
dwLengthHighequ_dwLengthHigh- $$
dwTypeequ_dwType- $$
?
_dwMemSize:dd0
dwMemSizeequ_dwMemSize- $$
?
...
;end of [SECTION .data1]
?
?
[SECTION .s16]
[BITS16]
...
;得到内存块数(中断15h)
movebx,0
movdi,_MemChkBuf
.loop:
moveax,0E820h
movecx,20
movedx,0534D4150h
int15h
jcLABEL_MEM_CHK_FAIL;CF=1,出错
adddi,20
incdword[_dwMCRNumber]
cmpebx,0;CF=0,ebx=0,则表示已经检测到最后一个内存块
jne.loop;CF=0,ebx!=0,表示尚未检测最后一个内存块
jmpLABEL_MEM_CHK_OK
LABEL_MEM_CHK_FAIL:
movdword[_dwMCRNum],0
LABEL_MEM_CHK_OK:
...(其他和检测内存块不相关的代码)
?
******************************************************************************************************************************************************
[SECTION .s32]中定义的函数DispMemSize:
DispMemSize:
pushesi
?? ? ? ?pushedi
pushecx
?
movesi, MemChkBuf
movecx, [dwMCRNumber];for(int i=0;i<[MCRNumber];i++)//每次得到一个ARDS
?
?? ? ?;注意到, ds:esi ==> MemChkBuf ,是一个线性结构; ?es:edi ==> ARDStruct,是二维数组
?
.loop: ?;{
movedx, 5 ?; ?for(int j=0;j<5;j++) //每次得到一个ARDS中的成员
movedi, ARDStruct ?; ?{//依次显示BaseAddrLow,BaseAddrHigh,LengthLow,
.1: ?; ? ? ? ? ? ? LengthHigh,Type
pushdword [esi] ?;
callDispInt ?; ? ?DispInt(MemChkBuf[j*4]); //显示一个成员,一个成员有四个字节dword
popeax?? ? ? ? ?; ? ?db-> BYTE, ?dw->WORD, ?dd->DWORD
stosd ?; ? ?ARDStruct[j*4] = MemChkBuf[j*4]; ? ? ? stosd指令:将eax的四个字节放到es:edi(ARDStruct)中
addesi, 4 ?;
decedx ?;
cmpedx, 0 ?;
jnz.1?? ? ? ? ?; ?}
callDispReturn ?; ?printf("\n");
?
cmpdword [dwType], 1 ? ? ? ? ?; ?if(Type == AddressRangeMemory) ? ? ? ? ; 通过上面stosd,已经填充好了dwType
jne.2?? ? ? ? ? ? ? ? ? ? ? ? ? ; ?{
moveax, [dwBaseAddrLow] ;
addeax, [dwLengthLow] ? ? ? ;
cmpeax, [dwMemSize] ? ? ? ? ?; ? ?if(BaseAddrLow + LengthLow >= MemSize)
jb.2 ??; ? ?jb==jump below
mov[dwMemSize], eax ? ? ? ? ?;MemSize = BaseAddrLow + LengthLow; 等号右边是当前这个内存块最后一个字节的地址
.2: ??; ?}
loop.loop ??;}
??;
callDispReturn?? ? ? ? ? ? ? ? ? ;printf("\n");
pushszRAMSize ??;
callDispStr ??;printf("RAM size:");
addesp, 4 ??;
??;
pushdword [dwMemSize] ;
callDispInt ??;DispInt(MemSize);
addesp, 4 ??;
?
popecx
popedi
popesi
ret