计算机器内存数量+引入和显示ARDS成员
2015-09-16 21:43
423 查看
【1】README
1.1) 本代码在于读取内存中多个 内存段的地址范围描述符结构体(ARDS),有多少个内存段可以用;1.2) source code and images in the blog from orange’s implemention of a os
1.3) the comments towards code are built by myself , which proves to be a key point ,in my opinion.
1.4) for complete code , please visit https://github.com/pacosonTang/Orange-s-OS/blob/master/p75.asm
Other)要知道,os 必须要知道内存的内容,以便进行内存管理。
【2】source code
2.1)得到内存数; 得到内存数 begin mov ebx, 0 mov di, _MemChkBuf ; _MemChkBuf: times 256 db 0, 缓冲区 .loop: mov eax, 0E820h mov ecx, 20 mov edx, 0534D4150h int 15h ; 每次中断,都把内存数据(不同内存段的描述和大小) copy 到 缓冲区_MemChkBuf中, jc LABEL_MEM_CHK_FAIL ; jump if carry(CF=1), cf=0表示读取内存信息没有错误 add di, 20 ; es:di 指向一个地址范围描述符结构 ARDS inc dword [_dwMCRNumber]; _dwMCRNumber: dd 0 ; Memory Check Result cmp ebx, 0 ; ebx 存储着下一个地址描述符所需要的后续值; jne .loop jmp LABEL_MEM_CHK_OK LABEL_MEM_CHK_FAIL: mov dword [_dwMCRNumber], 0 LABEL_MEM_CHK_OK: ; 得到内存数 over
代码步骤
step1)每次中断,都把不同内存段的 地址范围描述符结构体 copy 到 缓冲区_MemChkBuf中(连续地址),而缓冲区有256Bytes,而结构体有20B,所以只能copy 12个 结构体;copy完后,以便进行数据分析;
step2)如果内存段的 ARDS 没有读取出错的话,那么就将 内存数变量_dwMCRNumber 自加1 ;
Conclusion:(干货)
每次中断,都把不同内存段的 地址范围描述符结构体 copy 到 缓冲区_MemChkBuf中,显然,整个内存是分为多个内存段的,然后内存段是由地址范围描述符结构体(ARDS)来描述的。
(由图知:ARDS的size=20Bytes)
2.2)读取内存数据并显示
; call DispMemSize; 由保护模式的 显示内存信息 跳转到这里 DispMemSize: push esi push edi push ecx ; _MemChkBuf: times 256 db 0 ; MemChkBuf equ _MemChkBuf - $$ ; $$ == LABEL_DATA mov esi, MemChkBuf ; 他就是 存放内存描述符结构体 的 缓冲区,共256个字节,每个结构体=20字节,所以最多存放12个结构体 ; _ARDStruct: ; Address Range Descriptor Structure 地址范围描述符结构体 ; _dwBaseAddrLow: dd 0 基地址低32位 ; _dwBaseAddrHigh: dd 0 基地址高32位 ; _dwLengthLow: dd 0 长度的低32位 ; _dwLengthHigh: dd 0 长度的高32位 ; _dwType: dd 0 这个地址范围的地址类型 mov ecx, [dwMCRNumber]; 外循环 for(int i=0;i<[MCRNumber];i++)//每次得到一个ARDS , line_113已经得到其内存数了,cur_line_328, .loop: ;{ loop 的循环数 == ecx ,上行代码已经赋值 mov edx, 5 ; 内循环 for(int j=0;j<5;j++) //每次得到一个ARDS中的成员 ; ARDStruct equ _ARDStruct - $$ ; dwBaseAddrLow equ _dwBaseAddrLow - $$ ; dwBaseAddrHigh equ _dwBaseAddrHigh - $$ ; dwLengthLow equ _dwLengthLow - $$ ; dwLengthHigh equ _dwLengthHigh - $$ ; dwType equ _dwType - $$ mov edi, ARDStruct ; {//依次显示BaseAddrLow,BaseAddrHigh,LengthLow, .1: ; LengthHigh,Type push dword [esi] ; cur_line_343, line_318 mov esi, MemChkBuf,offset=esi,esi += 4; ; line_113在计算内存数时,已经将全部ARDS copy 到 缓冲区了 call DispInt ; DispInt(MemChkBuf[j*4]); // 显示一个成员 pop eax ; 将偏移地址 弹出到 eax ; cur_line_347, line_340: mov edi, ARDStruct stosd ; ARDStruct[j*4] = MemChkBuf[j*4]; eax copy到 edi 指向的目的地址(ARDStruct) ; 为什么要吧内存段描述符结构体从缓冲区copy到ARDS暂存呢?因为下面代码要用到变量:dwType + dwBaseAddrLow + dwLengthLow add esi, 4 ; cur_line_348, line_318 mov esi, MemChkBuf (256个0的内存空间的偏移地址) dec edx ; edx == 总循环次数(5--) cmp edx, 0 ; jnz .1 ; } 就这样循环下去吧,直到为0为止; call DispReturn ; printf("\n"); cmp dword [dwType], 1 ; if(Type == AddressRangeMemory)(该段内存可用的话) , 此刻的 dwType 是由line_349从缓冲区写入的,cur_line_357; jne .2 ; { ; 如果该内存不可用的话,跳转到 .2; mov eax, [dwBaseAddrLow]; 基地址的低32位 add eax, [dwLengthLow] ; 长度的低32位 cmp eax, [dwMemSize] ; if(BaseAddrLow + LengthLow > MemSize-内存大小),MemSize初始化为0;求最大内存范围值 jb .2 ; jb:无符号小于则跳转 ; _dwMemSize: dd 0 ; dwMemSize equ _dwMemSize - $$ mov [dwMemSize], eax ; MemSize = BaseAddrLow + LengthLow; .2: ; } ; Type==AddressRangeReserved (该段内存不可用的话) loop .loop ;} ; call DispReturn ;printf("\n"); push szRAMSize ; _szRAMSize db "RAM size:", 0 ;字符串以 0 结尾 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
代码步骤:(干货)
step1)首先要知道,上一段代码已经算出了内存段(块)的个数 dwMCRNumber 和 吧 内存各个ARDS copy 到了缓冲区MemChkBuf中,我们这里的代码需要用这个个数 dwMCRNumber 和这个 存储有 各个 ARDS 数据的缓冲区MemChkBuf;
step2)通过双循环,读取每个ARDS的各个成员的值并打印,外循环个数为内存段(块)个数,内循环个数=5(因为ARDS有5个成员), 并将缓冲区中每个 ARDS 暂存在 ARDS结构中,以便下面代码取变量值;
step3)继续说循环,内循环结束后,比较dwType(内存块类型),判断该内存段是否可用,不可用,进入下一次外循环;若可用,继续判断dwBaseAddrLow(基地址的低32位) + dwLengthLow(长度的低32位) 是否大于最大内存地址dwMemSize, 总之dwMemSize 取 它们和的最大值;外循环ending
step4)最后打印出 最大内存地址 dwMemSize;
相关文章推荐
- NOIP2014 无线网络发射器选址
- TCP/IP连接服务器备忘
- Hdu5441 2015长春赛区网络赛
- 计算机网络学习 :p2p通信方式简单理解
- Android采用HttpClient下载图片
- win8的prolific USB-to-serial comm port驱动安装问题解决
- HTTP协议中POST和GET的区别
- iOS项目开发实战——使用AFNetworking进行Http Get请求
- Linux 网络编程之tcp/ip
- 计算机网络学习 :网络分层图解
- 2015区域赛长春网络赛 Travel
- NetworkRequest 网络请求
- VB6.0 GetTcpTable 使用详解
- 数据结构与算法的笔记(一)
- 计算机网络学习 :互联网与万维网的区别
- android解析JSON,XML数据的请求网络工具类
- flex通过HTTPService与java通信例子
- TCP控制拥塞的四种算法:慢开始,拥塞避免,快重传,快恢复
- windows中VMware Workstation环境下的Linux网络设置Bridge方法设置
- TCP 的那些事儿(下)