5.1获取物理内存容量

news2025/2/27 23:23:53

5.1获取物理内存容量

5.1.1学习Linux获取内存的方法

在 Linux 2.6 内核中, 是用 detect_memory 函数来获取内存容量的 其函数在本质上是通过调用 BIOS 中断 0x15 实现的, 分别是BIOS 中断 0x15 的3个子功能, 子功能号要存放到寄存器EAx或Ax中, 如下:
1.EAx=0xE820 遍历主机上全部内存。
2.Ax=0xE801分别检测低 15MB 和 16MB~4GB 的内存, 最大支持 4GB。
3.AH=0x88 最多检测出 64MB 内存, 实际内存超过此容量也按照 64MB 返回。

利用BIOS中断0x15子功能0xe820获取内存

BIOS 中断 0x15 的子功能 0xE820 能够获取系统的内存布局, 由于系统内存各部分的类型属性不同,BIOS 就按照类型属性来划分这片系统内存, 所以这种查询呈迭代式, 每次 BIOS 只返回一种类型的内存信息 直到将所有内存类型返回完毕。子功能 0xE820 的强大之处是返回的内存信息较丰宫, 包括多个属性字段, 所以需要一种格式结构来组织这些数据。内存信息的内容是用地址范围描述符来描述的, 用于存储这种描述符的结构称之为地址范围描述符。
请添加图片描述
此结构中的字段大小都是4字节, 共5个字段, 所以此结构大小为20字节。 每次 int0x15 之后, BIOS就返回这样一个结构的数据。 注意, ARDS 结构中用 64位宽度的属性来描述这段内存基地址 (起始地址)及其长度, 所以表中的基地址和长度都分为低 32位和高 32 位两部分。
Type 字段用来描述这段内存的类型, 这里所谓的类型是说明这段内存的用途, 即其是可以被操作系统使用, 还是保留起来不能用。 Type字段的具体意义见下表:
请添加图片描述
BIOS 中断只是一段函数例程, 调用它就要为其提供参数现在介绍下 BIOS 中断 0x15 的 0xe820子功能需要哪些参数。先介绍下此中断例程的调用方法。 表5-3 所示是使用此中断的方法, 分输入和输出两部分。
请添加图片描述
请添加图片描述
ECX 寄存器和 ES: DI 寄存器, 是典型的 “值-结果” 型参数, 即调用方提供了两个变量作为被调用函数的参数, 一个变量是缓冲区指针, 另一个变量是缓冲区大小。 被调用函数在缓冲区中写入数据后, 将实际所写入的字节数记录到缓冲区大小变量中。
根据表 5-3 中的说明, 此中断的调用步骤如下。
(1) 填写好 “调用前输入” 中列出的寄存器。
(2)执行中断调用 int 0x15。
(3) 在CF位为0的情况下, “返回后输出″ 中对应的寄存器便会有对应的结果。

利用BIOS中断0x15子功能0xe801获取内存

另一个获取内存容量的方法是BIOS 0xl5 中断的子功能 0xE801。
此方法虽然简单,但功能不强大, 最大只能识别4GB 内存, 不过这对咱们32位地址总线足够了。 稍微有点不便的是该方法检测到的内存是分别放置在两组寄存器中的。
请添加图片描述
此中断的调用步骤如下。
(1) 将AX寄存器写入0xE801。
(2) 执行中断调用 int 0x15。
(3) 在CF 位为0的情况下, “返回后输出” 中对应的寄存器便会有对应的结果。

利用BIOS中断的0x15子功能0x88获取内存

最后一个获取内存的方法也同样是 BIOS 0x15 中断, 子功能号是 0x88。 该方法使用最简单, 但功能也最简单, 简单到只能识别最大 64MB 的内存。 即使内存容量大于 64MB, 也只会显示 63MB, 大家可以自己在bochs中试验下。为什么只显示到63M呢? 因为此中断只会显示 1MB之上的内存,不包括这 1MB
请添加图片描述
中断返回后, Ax寄存器中的值, 其单位是 1KB。 此中断的调用步骤如下。
(1)将 AX 寄存器写入 0x88
(2) 执行中断调用 int0x15
(3)在CF位为0的情况下, “返回后输出” 中对应的寄存器便会有对应的结果。

##实际代码获取物理内存

;-------  int 15h eax = 0000E820h ,edx = 534D4150h ('SMAP') 获取内存布局  -------

   xor ebx, ebx		      ;第一次调用时,ebx值要为0
   mov edx, 0x534d4150	      ;edx只赋值一次,循环体中不会改变
   mov di, ards_buf	      ;ards结构缓冲区
.e820_mem_get_loop:	      ;循环获取每个ARDS内存范围描述结构
   mov eax, 0x0000e820	      ;执行int 0x15,eax值变为0x534d4150,所以每次执行int前都要更新为子功能号。
   mov ecx, 20		      ;ARDS地址范围描述符结构大小是20字节
   int 0x15
   jc .e820_failed_so_try_e801   ;若cf位为1则有错误发生,尝试0xe801子功能  汇编语言jc指令,当flags寄存器中的CF位为1时触发
   add di, cx		      ;使di增加20字节指向缓冲区中新的ARDS结构位置
   inc word [ards_nr]	      ;记录ARDS数量  对地址中的内容+1再送回给地址
   cmp ebx, 0		      ;若ebx为0且cf不为1,这说明ards全部返回,当前已是最后一个   cmp比较ebx与0是否相等,相等ZF=1,不相等ZF=0
   jnz .e820_mem_get_loop ;flagsZF位不为0/不等于时跳转执行

;在所有ards结构中,找出(base_add_low + length_low)的最大值,即内存的容量。
   mov cx, [ards_nr]	      ;遍历每一个ARDS结构体,循环次数是ARDS的数量
   mov ebx, ards_buf 
   xor edx, edx		      ;edx为最大的内存容量,在此先清0
.find_max_mem_area:	      ;无须判断type是否为1,最大的内存块一定是可被使用
   mov eax, [ebx]	      ;base_add_low
   add eax, [ebx+8]	      ;length_low
   add ebx, 20		      ;指向缓冲区中下一个ARDS结构
   cmp edx, eax		      ;冒泡排序,找出最大,edx寄存器始终是最大的内存容量
   jge .next_ards          ;jge大于或者等于转移指令
   mov edx, eax		      ;edx为总内存大小
.next_ards:
   loop .find_max_mem_area
   jmp .mem_get_ok

;------  int 15h ax = E801h 获取内存大小,最大支持4G  ------
; 返回后, ax cx 值一样,以KB为单位,bx dx值一样,64KB为单位
; 在ax和cx寄存器中为低16M,在bx和dx寄存器中为16MB到4G。
.e820_failed_so_try_e801:
   mov ax,0xe801
   int 0x15
   jc .e801_failed_so_try88   ;若当前e801方法失败,就尝试0x88方法

;1 先算出低15M的内存,ax和cx中是以KB为单位的内存数量,将其转换为以byte为单位
   mov cx,0x400	     ;cx和ax值一样,cx用做乘数
   mul cx 
   shl edx,16
   and eax,0x0000FFFF
   or edx,eax
   add edx, 0x100000 ;ax只是15MB,故要加1MB
   mov esi,edx	     ;先把低15MB的内存容量存入esi寄存器备份

;2 再将16MB以上的内存转换为byte为单位,寄存器bx和dx中是以64KB为单位的内存数量
   xor eax,eax
   mov ax,bx		
   mov ecx, 0x10000	;0x10000十进制为64KB
   mul ecx		;32位乘法,默认的被乘数是eax,积为64,32位存入edx,32位存入eax.
   add esi,eax		;由于此方法只能测出4G以内的内存,32位eax足够了,edx肯定为0,只加eax便可
   mov edx,esi		;edx为总内存大小
   jmp .mem_get_ok

;-----------------  int 15h ah = 0x88 获取内存大小,只能获取64M之内  ----------
.e801_failed_so_try88: 
   ;int 15后,ax存入的是以kb为单位的内存容量
   mov  ah, 0x88
   int  0x15
   jc .error_hlt
   and eax,0x0000FFFF
      
   ;16位乘法,被乘数是ax,积为32.积的高16位在dx中,积的低16位在ax中
   mov cx, 0x400     ;0x400等于1024,将ax中的内存容量换为以byte为单位
   mul cx
   shl edx, 16	     ;把dx移到高16位
   or edx, eax	     ;把积的低16位组合到edx,32位的积
   add edx,0x100000  ;0x88子功能只会返回1MB以上的内存,故实际内存大小要加上1MB

.mem_get_ok:
   mov [total_mem_bytes], edx	 ;将内存换为byte单位后存入total_mem_bytes处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/9598.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构与算法】BFS 和 DFS

🔥 本文由 程序喵正在路上 原创,CSDN首发! 💖 系列专栏:数据结构与算法 🌠 首发时间:2022年11月16日 🦋 欢迎关注🖱点赞👍收藏🌟留言&#x1f43e…

关于混合SDN网络的统一信息模型方面研究事件通知的多样性问题

关于混合SDN网络的统一信息模型方面研究事件通知的多样性问题面向混合SDN中异构设备的混合域发现协议Hybrid Domain Discovery Protocol (HDDP)HDDP的主要特点混合域发现协议(HDDP)协议介绍过程总结申明: 未经许可,禁止以任何形式转载,若要引…

阿里云研发工程师刘睿:阿里云消息生态及最佳实践

2022 年 9 月 24 日,阿里云用户组(AUG)第 12 期活动在厦门举办。活动现场,阿里云消息中间件研发工程师刘睿,向参会企业代表分享了阿里云消息生态及最佳实践。本文根据演讲内容整理而成。 众所周知,消息中间…

智能生活 App 垂直品类- IPC SDK 架构及快速集成配置(安卓版)

除了通用设备功能的应用开发,针对部分常见的全屋智能场景设备,智能生活 App SDK 提供了单独的垂直品类 SDK。包括智能摄像机 SDK、智能门锁 SDK、扫地机机器人 SDK、智能照明控制 SDK 等。 基于 智能生活 App SDK,垂直品类 SDK 面向这些特定…

适合编程初学者的开源博客系统(Flutter版)

目标 为编程初学者打造入门学习项目,使用各种主流编程语言来实现。让想学编程的,一个都不落下。 上述基本涵盖了当前编程开发所有主流语言(我这里说的主流,直白点讲就是互联网公司都在用的)。 左侧为前端版本&#x…

即将学习3D建模看过来,超高性价比电脑推荐

虽说建模还是台式最好,但是需要外出或者带回家工作的时候还是不方便的❌,咱们来看下怎么挑~ 我们使用的建模软件为3DsMax、maya、zbrush等 建模的时候,对显卡和内存的要求较高🉐 显卡越好,模型面数多了也…

pwn调试环境搭建

应用场景 不同的pwn题有不同的环境要求,堆题要求更多,patchelf可以满足一定场景的实现,但终究不如在实际对应的环境中搭建。如何快速搭建一个高效节省资源的环境也是一个不小的问题。 方法 高效节省资源:一个主要调试环境多个运…

CE修改植物大战僵尸-天上无限掉落阳光(小宇特详解)

CE修改植物大战僵尸-天上无限掉落阳光 里是CE修改植物大战僵尸的第三个博客,其他的操作请看我之前的博客。 天上无限掉落阳光。 这里说明一下版本: CE:CE6.8 植物大战僵尸版本:植物大战僵尸95版 具体步骤 我们在刚出现阳光…

英国Essay写作降重方法有哪些?

英国留学生写Essay的时候会遇到抄袭率比较高的情况,当参考别人的文章的同时,不知不觉也就会让文章的重复率有所增加,有效减少重复率修改的方法你清楚吗?下文为大家讲解一下降低英国Essay写作降重的方法。 When British overseas s…

汇编语言实验8:BIOS/DOS功能调用与宏指令程序设计

《汇编语言程序设计》实验报告实验八 BIOS/DOS功能调用与宏指令程序设计1. 实验目的2. 实验任务3.1 BIOS/DOS及宏汇编程序题目设计3.2 编写代码3.3 代码分析3.4 运行测试4. 实验总结实验八 BIOS/DOS功能调用与宏指令程序设计 1. 实验目的 掌握汇编语言程序设计的基本方法和技…

基于工业级4G5G路由器大型设备远程无线监控方案

一、行业背景进入21世纪,我国经济持续高速发展,全球各地的企业对大型设备的需求日益旺盛,例如工业锅炉、数控车床、医疗器械等,在产品服务业全球的时候,产品厂家需要对所有在外的设备进行远程监控管理,实时…

Linux 内存管理知识总结(二)

Linux 内存管理框架 传统的多核运算是使用 SMP(Symmetric Multi-Processor )模式:将多个处理器与一个集中的存储器和 I/O 总线相连,所有处理器访问同一个物理存储器,因此 SMP 系统有时也被称为一致存储器访问(UMA)结构…

Leetcode刷题day1|数组一|704.二分查找,27.移除元素,35.搜索插入位置

文章目录一、面试中数组相关理论知识二、二分查找问题思路注意事项AC代码三、移除元素思路注意事项AC代码四、寻找插入位置思路AC代码五、总结二分法|二分查找法|二分搜索法|二分易错点相关概念代码实现一、面试中数组相关理论知识 数组是非常基础的数据结构,在面试…

【树状数组】前缀和问题

一、引子 给你一个数组 nums ,请你完成两类查询。 其中一类查询要求更新数组 nums 下标对应的值另一类查询要求返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的和 题目只是一个用来检测我们思想的东西,比如这…

Android BottomSheet总结

文章目录Android BottomSheet总结BottomSheetBottomSheetDialogBottomSheetDialogFragment全屏无阴影BottomSheetDialogFragment代码下载Android BottomSheet总结 BottomSheet XML布局&#xff1a; <?xml version"1.0" encoding"utf-8"?> <an…

C++ 条件变量的使用

绪论 并发编程纷繁复杂&#xff0c;其中用于线程同步的主要工具——条件变量&#xff0c;虽然精悍&#xff0c;但是要想正确灵活的运用却并不容易。 对于条件变量的理解有三个难点&#xff1a; 为什么wait函数需要将解锁和阻塞、唤醒和上锁这两对操作编程原子的&#xff1f;为…

MCMC学习笔记-马尔科夫链概述

参考文章&#xff1a;MCMC(二)马尔科夫链 - 刘建平Pinard - 博客园 写给小白看的马尔科夫链&#xff08;Markov Chain&#xff09;最佳入门教程_许进进的博客-CSDN博客_markov链 目录 1.马尔科夫链概述 1.1股票市场模型 2.马尔科夫链模型状态转移矩阵的性质 (本节重点) 2.…

小程序容器技术加持下,企业自主打造小程序生态

小程序是一种不用下载就能使用的应用&#xff0c;也是一项门槛非常高的创新&#xff0c;经过将近两年的发展&#xff0c;已经构造了新的小程序开发环境和开发者生态。 据对公开资料进行统计&#xff0c;2021年全网小程序数量已超700万&#xff0c;其中微信小程序开发者突破300…

java使用world模板动态生成PDF文件

根据项目需求&#xff0c;需要用到一个功能&#xff0c;根据页面参数需要动态的生成一个world&#xff0c;并将world生成两份PDF文件&#xff0c;一份正式文件&#xff0c;一份临时的电子文件&#xff08;带有二维码&#xff0c;扫描可以下载正式文件的电子版本&#xff09;。同…