自制操作系统_02_使用汇编进行内存检测

[org 0x1000]

; 校验用的, 这里会被读到 0x1000处
dw 0xa0a0


mov si, loading_log
call print


detect_memory:
    ; 设置检测内存的buffer位置
    mov ax, 0
    mov es, ax
    mov edi, mem_task_buffer

    ; 固定签名
    mov edx, 0x534d4150

    ; 置为0, 每次系统调用会修改这个寄存器
    xor ebx, ebx

    ; 保存的目的地
    mov di, mem_task_buffer

    .next:
        ; 子功能号
        mov eax, 0xe820
        ; ards 结构的大小 (字节)
        mov cx, 20
        ; 调用中断
        int 0x15
        ; 如果cf置位, 表示出错了
        jc error

        ; 计算下一个内存结构体保存的首地址
        add di, cx

        inc word [mem_task_count]

        ; 不为0 说明检查未完成
        cmp ebx, 0
        jnz .next


    mov si, detect_memory_log
    call print

    ; 循环结构体内的值
    mov cx, [mem_task_count]
    ; 初始偏移量
    mov si, 0
    .show
        mov eax, [mem_task_buffer + si]  ; 基地址 低32位
        mov ebx, [mem_task_buffer + si + 8]  ; 内存长度的低32位
        mov edx, [mem_task_buffer + si + 16]  ; 本段内存类型  1: 可以使用, 2: 内存使用或者被保留中, 其他: 未定义

        add si, 20
        xchg bx, bx  ; bochs 的魔数, 代码执行到这里会停下
        loop .show




jmp $

print:
    push ax
    mov ah, 0x0e
    .show
        mov al,[si]
        cmp al, 0
        jz .end
        int 0x10
        inc si
        jmp .show
    .end
        pop ax
        ret


loading_log:
    db 'Loader Start', 13, 10, 0

detect_memory_log:
    db 'detect_memory end', 13, 10, 0

checking:
    db 'check ing', 13, 10, 0

error:
    mov si, .error_msg
    call print
    hlt  ; 让 CPU 停止
    jmp $
    ret
    .error_msg db "Loader Error!!!", 10, 13, 0


mem_task_count:
    dw 0

; 用来存放检测内存结果的结构体
mem_task_buffer: