zoukankan      html  css  js  c++  java
  • 32 获取物理内存容量 下

    参考

    https://blog.51cto.com/13475106/category6.html及狄泰软件相关课程

    获取物理内存容量

    上面介绍的是基础功能,这里介绍的是高级功能操作系统-获取物理内存容量
    参数的设置
    操作系统-获取物理内存容量
    edx是bios所需要的值,不做深究
    地址范围描述结果(ARDS)
    操作系统-获取物理内存容量操作系统-获取物理内存容量

    代码实验

    %include "inc.asm"
    
    org 0x9000
    
    jmp ENTRY_SEGMENT
    
    [section .gdt]
    
    ; GDT definition
    
    ;                                     段基址,           段界限,       段属性
    
    GDT_ENTRY       :     Descriptor        0,                0,           0
    
    CODE32_DESC     :     Descriptor        0,        Code32SegLen - 1,    DA_C + DA_32
    
    VIDEO_DESC      :     Descriptor     0xB8000,         0x07FFF,         DA_DRWA + DA_32
    
    DATA32_DESC     :     Descriptor        0,        Data32SegLen - 1,    DA_DRW + DA_32
    
    STACK32_DESC    :     Descriptor        0,         TopOfStack32,       DA_DRW + DA_32
    
    ; GDT end
    
    GdtLen    equ   $ - GDT_ENTRY
    
    GdtPtr:
    
              dw   GdtLen - 1
    
              dd   0
    
    ; GDT Selector
    
    Code32Selector   equ (0x0001 << 3) + SA_TIG + SA_RPL0
    
    VideoSelector    equ (0x0002 << 3) + SA_TIG + SA_RPL0
    
    Data32Selector   equ (0x0003 << 3) + SA_TIG + SA_RPL0
    
    Stack32Selector  equ (0x0004 << 3) + SA_TIG + SA_RPL0
    
    ; end of [section .gdt]
    
    TopOfStack16    equ 0x7c00
    
    [section .dat]
    
    [bits 32]
    
    DATA32_SEGMENT:
    
        DTOS               db  "D.T.OS!", 0
    
        DTOS_OFFSET        equ DTOS - $$
    
        HELLO_WORLD        db  "Hello World!", 0
    
        HELLO_WORLD_OFFSET equ HELLO_WORLD - $$
    
    Data32SegLen equ $ - DATA32_SEGMENT
    
    ;
    
    MEM_SIZE              times    4      db  0
    
    MEM_ARDS_NUM          times    4      db  0      ; int mem_ards_num = 0;
    
    MEM_ARDS              times 64 * 20   db  0 
    
    [section .s16]
    
    [bits 16]
    
    ENTRY_SEGMENT:
    
        mov ax, cs
    
        mov ds, ax
    
        mov es, ax
    
        mov ss, ax
    
        mov sp, TopOfStack16
    
        ; get InitSysMemBuf  infomation
    
        call InitSysMemBuf
    
        ; initialize GDT for 32 bits code segment
    
        mov esi, CODE32_SEGMENT
    
        mov edi, CODE32_DESC
    
        call InitDescItem
    
        mov esi, DATA32_SEGMENT
    
        mov edi, DATA32_DESC
    
        call InitDescItem
    
        mov esi, STACK32_SEGMENT
    
        mov edi, STACK32_DESC
    
        call InitDescItem
    
        ; initialize GDT pointer struct
    
        mov eax, 0
    
        mov ax, ds
    
        shl eax, 4
    
        add eax, GDT_ENTRY
    
        mov dword [GdtPtr + 2], eax
    
        ; 1. load GDT
    
        lgdt [GdtPtr]
    
        ; 2. close interrupt
    
        cli 
    
        ; 3. open A20
    
        in al, 0x92
    
        or al, 00000010b
    
        out 0x92, al
    
        ; 4. enter protect mode
    
        mov eax, cr0
    
        or eax, 0x01
    
        mov cr0, eax
    
        ; 5. jump to 32 bits code
    
        jmp dword Code32Selector : 0
    
    ; esi    --> code segment label
    
    ; edi    --> descriptor label
    
    InitDescItem:
    
        push eax
    
        mov eax, 0
    
        mov ax, cs
    
        shl eax, 4
    
        add eax, esi
    
        mov word [edi + 2], ax
    
        shr eax, 16
    
        mov byte [edi + 4], al
    
        mov byte [edi + 7], ah
    
        pop eax
    
        ret
    
    ;
    
    ;
    
    GetMemSize:
    
        push eax
    
        push ebx
    
        push ecx
    
        push edx
    
        mov dword [MEM_SIZE], 0
    
        xor eax, eax
    
        mov eax, 0xE801
    
        int 0x15
    
        jc geterr
    
        shl eax, 10   ; eax = eax * 1024;
    
        shl ebx, 6    ; ebx = ebx * 64;
    
        shl ebx, 10   ; ebx = ebx * 1024;
    
        mov ecx, 1
    
        shl ecx, 20   ; ecx = 1MB
    
        add dword [MEM_SIZE], eax
    
        add dword [MEM_SIZE], ebx
    
        add dword [MEM_SIZE], ecx
    
        jmp getok
    
    geterr:
    
        mov dword [MEM_SIZE], 0
    
    getok:
    
        pop edx
    
        pop ecx
    
        pop ebx
    
        pop eax
    
        ret
    
    ; return 
    
    ;    eax  --> 0 : succeed      1 : failed
    
    InitSysMemBuf: 
    
         push edi
    
         push ebx
    
         push ecx
    
         push edx
    
         mov edi, MEM_ARDS
    
         mov ebx, 0
    
    memerr:
    
         mov dword [MEM_ARDS_NUM], 0
    
         mov eax, 1
    
    doloop:
    
         mov eax, 0xE820
    
         mov edx, 0x534D4150
    
         mov ecx, 20
    
         int 0x15
    
         jc memerr
    
         add edi, 20
    
         inc dword [MEM_ARDS_NUM]
    
         cmp ebx, 0
    
         jne doloop
    
         mov eax,0
    
         jmp memok
    
    memok:   
    
         pop edx
    
         pop ecx
    
         pop ebx
    
         pop edi
    
         ret
    
    [section .s32]
    
    [bits 32]
    
    CODE32_SEGMENT:   
    
        mov ax, VideoSelector
    
        mov gs, ax
    
        mov ax, Stack32Selector
    
        mov ss, ax
    
        mov eax, TopOfStack32
    
        mov esp, eax
    
        mov ax, Data32Selector
    
        mov ds, ax
    
        mov ebp, DTOS_OFFSET
    
        mov bx, 0x0C
    
        mov dh, 12
    
        mov dl, 33
    
        call PrintString
    
        mov ebp, HELLO_WORLD_OFFSET
    
        mov bx, 0x0C
    
        mov dh, 13
    
        mov dl, 31
    
        call PrintString
    
        jmp $
    
    ; ds:ebp    --> string address
    
    ; bx        --> attribute
    
    ; dx        --> dh : row, dl : col
    
    PrintString:
    
        push ebp
    
        push eax
    
        push edi
    
        push cx
    
        push dx
    
    print:
    
        mov cl, [ds:ebp]
    
        cmp cl, 0
    
        je end
    
        mov eax, 80
    
        mul dh
    
        add al, dl
    
        shl eax, 1
    
        mov edi, eax
    
        mov ah, bl
    
        mov al, cl
    
        mov [gs:edi], ax
    
        inc ebp
    
        inc dl
    
        jmp print
    
    end:
    
        pop dx
    
        pop cx
    
        pop edi
    
        pop eax
    
        pop ebp
    
        ret
    
    Code32SegLen    equ    $ - CODE32_SEGMENT
    
    [section .gs]
    
    [bits 32]
    
    STACK32_SEGMENT:
    
        times 1024 * 4 db 0
    
    Stack32SegLen equ $ - STACK32_SEGMENT
    
    TopOfStack32  equ Stack32SegLen - 1
    

     

    操作系统-获取物理内存容量

    结果分析

    首先通反编译找到函数的调用地址,然后对该处设置地址,同时也对下个地址进行设置,同时打上断点,通过书写的函数,找到所需查看的地址,如下图所示
    操作系统-获取物理内存容量操作系统-获取物理内存容量操作系统-获取物理内存容量操作系统-获取物理内存容量
    首先查看全局函数0x904d的内存,发下为0是我们所需的结果,查看寄存器eax寄存器为0,说明调用成功,再次查看0x904d发现其为6,这次需要查看数组前六个元素,通过数组地址0x9051,发现其有起始地址,长度,类型,通过打印六次之后,所打印的结果为0,说明得到内存信息
    操作系统-获取物理内存容量操作系统-获取物理内存容量操作系统-获取物理内存容量

     

  • 相关阅读:
    C语言宏的定义和宏的使用方法(#define)
    C语言字符串拼接
    OC字符串与C语言字符串之间的相互转换
    C语言#include的用法
    NSSet集合
    NSArray 数组
    预定义宏,C语言预定义的宏详解
    主流C语言编译器介绍
    无法使用此电子邮件地址。请选择其他电子邮件地址
    可变大小、颜色边框、样式的UISwitch
  • 原文地址:https://www.cnblogs.com/lh03061238/p/14439588.html
Copyright © 2011-2022 走看看