计算机器内存数量+引入和显示ARDS成员
生活随笔
收集整理的這篇文章主要介紹了
计算机器内存数量+引入和显示ARDS成员
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【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, 0mov di, _MemChkBuf ; _MemChkBuf: times 256 db 0, 緩沖區 .loop:mov eax, 0E820hmov ecx, 20mov edx, 0534D4150hint 15h ; 每次中斷,都把內存數據(不同內存段的描述和大小) copy 到 緩沖區_MemChkBuf中,jc LABEL_MEM_CHK_FAIL ; jump if carry(CF=1), cf=0表示讀取內存信息沒有錯誤add di, 20 ; es:di 指向一個地址范圍描述符結構 ARDSinc dword [_dwMCRNumber]; _dwMCRNumber: dd 0 ; Memory Check Resultcmp ebx, 0 ; ebx 存儲著下一個地址描述符所需要的后續值;jne .loopjmp 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 esipush edipush ecx ; _MemChkBuf: times 256 db 0 ; MemChkBuf equ _MemChkBuf - $$; $$ == LABEL_DATAmov 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,Typepush 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, ARDStructstosd ; ARDStruct[j*4] = MemChkBuf[j*4]; eax copy到 edi 指向的目的地址(ARDStruct); 為什么要吧內存段描述符結構體從緩沖區copy到ARDS暫存呢?因為下面代碼要用到變量:dwType + dwBaseAddrLow + dwLengthLowadd 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 ecxpop edipop esiret- 代碼步驟:(干貨)
- 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成员的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 域名怎么停用(如何停用域名)
- 下一篇: 企业邮箱怎么搭建(企业邮箱搭建)