【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. 一个简单的NoSQL内存数据库—Berkeley DB基本操作的例子

    一个简单的NoSQL内存数据库—Berkeley DB基本操作的例子 最近,由于云计算的发展,数据库技术也从结构式数据库发展到NoSQL数据库,存储模式从结构化的关系存储到现在如火如荼的key/val ...

  2. Python 类的重写

    #!/usr/bin/env python # -*- coding:utf-8 -*- # @Time : 2017/11/7 22:46 # @Author : lijunjiang # @Fil ...

  3. GIT 的常规操作

    GIT 的常规操作 常规操作也是我自己平时常用的几个命令, 学自于 pro git 这本书中 git 配置文件 git的配置文件位置 针对所有用户:/etc/gitconfig 针对当前用户: -/. ...

  4. MySQL常见注意事项及优化

    MySQL常见注意事项 模糊查询 like 默认是对name字段建立了索引 注意:在使用模糊查询的时候,当% 在第一个字母的位置的时候,这个时候索引是无法被使用的.但是% 在其他的位置的时候,索引是可 ...

  5. Filter解决中文乱码问题

    1,FIlter中编码设置 编码设置一定要在跳转页面之前 public void doFilter(ServletRequest request, ServletResponse response, ...

  6. Android开发初期之后怎么提升?怎么才能叫精通?方向在哪?

    hi大头鬼hi Android开发专家     先mark一下,好多人我发现始终停留在两三年的水平上没有突破. 另外还有一个误区就是越底层越牛逼 第三个就是,我认识的大部分所谓的做过rom开发的对fr ...

  7. WinRAR4.20注册文件key文件注册码

    1.首先安装rar4.2官方版 2.在WinRAR已安装文件夹内新建文本文档,打开文档,把下面代码复制进去 RAR registration datawncnUnlimited Company Lic ...

  8. 微信小程序-关于日期选择器(input)

    小程序并没有input带有日期组件(只有picker组件带日期),要不自创,要不就用picker把选中的值放入input当中 wxml js 因为会触发input,所以禁用它就可以了

  9. js 原生方法获取所有兄弟节点

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  10. 在Linux下安装R语言软件

    安装环境: centos.R3.0.1 1.在终端下下载: #cd /usr/local/ #wget http://mirror.bjtu.edu.cn/cran/src/base/R-3/R-3. ...