【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;

计算机器内存数量+引入和显示ARDS成员的更多相关文章

  1. 如何正确查看Linux机器内存使用情况

    如何正确查看Linux机器内存使用情况 背景 只要工作上涉及到Linux机器,基本上都会有这样一个需求,查看内存使用情况,但是怎么看才正确呢?之前使用的是top命令,一直存在一个误区. 为什么top命 ...

  2. C# 计算字符串在控制台中的显示长度

    var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...

  3. PHP 计算出内存最高占用.

    PHP 计算出内存最高占用.   代码可以计算出内存是否完全被使用, ini设置处:memory_limit = 1024M  代码跑完将显示如下信息: memory_limit:320M  all ...

  4. aix 计算性内存和文件内存

    经过有客户问AIX   topas中内存(memory)一项显示的数值含义: MEMORY Real,MB    4096 % Comp     68.9 % Noncomp  22.6 % Clie ...

  5. Flutter实战视频-移动电商-59.购物车_计算商品价格和数量

    59.购物车_计算商品价格和数量 本节课主要是加上自动计算的功能 provide/cart.dart 在provide的类里面增加两个变量 cart_bottom.dart 三个组件因为我们都需要套一 ...

  6. 关于jquery计算页面元素数量

    这段jquery计算页面元素数量代码,能不能刷新页面直接输出数量,而不用点计算按钮 <scriptsrc="http://ajax.googleapis.com/ajax/libs/j ...

  7. C语言计算机器运行时间

    //计算机器运行时间 long i = 10000000L;clock_t start, finish;double duration;//测量一个事件持续的时间printf( "Time ...

  8. Redis Cluster机器内存充爆处理

    机器配置 系统:CentOS6.7 配置:4C8G 应用:Redis Cluster,实例化 现象 1.无法启动redis,启动后系统OOM,直接杀死 2.Redis: OOM command not ...

  9. linux 查看机器内存方法 (free命令)

    工作中遇到了统计机器内存的问题.记录一下. free命令可以查看那机器内存. 如下图单位是M 查看man free可以知道,也可以直接从/proc/meminfo文件中读取.

随机推荐

  1. AC日记——第K大的数 51nod 1105

    1105 第K大的数 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 数组A和数组B,里面都有n个整数.数组C共有n^2个整数,分别是A[0] * ...

  2. Codeforces Gym101522 C.Cheering-字符串 (La Salle-Pui Ching Programming Challenge 培正喇沙編程挑戰賽 2017)

    C.Cheering To boost contestants' performances in the 20th La Salle - Pui Ching Programming Challenge ...

  3. HDU 1025 Constructing Roads In JGShining's Kingdom[动态规划/nlogn求最长非递减子序列]

    Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65 ...

  4. BZOJ2748(DP)

    非常简单的DP题.类似背包的操作,按照音量改变值进行状态转移即可. #include <bits/stdc++.h> using namespace std; #define REP(i, ...

  5. Java IO 流 设计模式

    学过装饰模式后,大家会发现,它在Java语言中最著名的应用莫过于Java I/O标准为库的设计了.这一节将以处理Byte流为例,看看装饰模式是怎样得到应用的. 为什么不用继承而用装饰模式 我们知道Ja ...

  6. NOI模拟题4 Problem B: 小狐狸(fox)

    Solution 考虑分开统计朝向每一个方向的所有狐狸对答案的贡献. 比如说以向右为例, 我们用箭标表示每一只狐狸的方向, 用\('\)表示当前一步移动之前的每一只狐狸的位置. \[ \begin{a ...

  7. 通信API、使用Web Workers处理线程

    1.跨文档消息传输                                               要想接受从其他的窗口那里发过来的消息,就必须对窗口对象的message事件进行监视. w ...

  8. iOS 定位坐标不准确的相关整理及解决方案汇总

    这几天处理定位相关的代码,彻彻底底的被火星坐标恶心到了. 恶心列表 从 CLLocationManager 取出来的经纬度放到 mapView 上显示,是错的! 从 CLLocationManager ...

  9. Java加载Properties配置文件工具类

    Java加载Properties配置文件工具类 import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; ...

  10. linux 之体验(JDK7+Tomcat7+MySQL5.5)部署环境

    ---------------------------------------------------------------------------------------------------- ...