0xE820 方法1
总共有三种,我们只需要了解一种,因为它一般不会出错
实际物理内存 和 检测出来的结果 之间总是相差1MB的,原因是因为有些老的ISA设备要用到地址15MB以上的内存作为缓冲区,也就是说此缓冲区的大小为1MB,操作系统不可以访问这段内存
3.代码Total_Memory_Bytes dd 0 ;以字节形式表示的内存大小 存放在此处 MemoryBuf times 244 db 0 ; 获取到的全部的信息 存放在此处 ARDS_Count dw 0 ;获取到了几个ARDS结构 ; ; Loader_Start: MOV EBX, 0x0 ;ARDS的后续值 第一次必须为0 MOV EDX, 0x534d4150 ; 固定的签名标记 MOV DI, MemoryBuf ;ES:DI 的地址 存放获取到的信息 .E820_MemGetLoop: ;方法1的循环 MOV EAX, 0x0000E820 ; 功能号 MOV ECX, 0x14 ; 指定ARDS结构体的大小 INT 0x15 ;执行中断 JC .E820_Fail_Try_E801 ;若C位为1 用另外一种方式去读取 ;若读取成功 Add DI, 0x14; ;偏移到下一个保存ARDS结构的位置 INC word [ARDS_Count] ;ARDS的个数++ CMP EBX, 0 ; EBX = 0 表示全部的读取 结束了 JNZ .E820_MemGetLoop ; 没结束 继续读取 ;下面就是全部读取完成 判断出最大的那个内存 MOV CX, [ARDS_Count] ; MOV EBX, MemoryBuf MOV EDX, 0x0 ;EDX 保存最大的那个内存 先清0 .Find_Max_Memory: MOV EAX, [EBX] ;baseAddLow + LengthLow ADD EAX, [EBX+8] CMP EDX, EAX ; 比较前一次的最大值 和 这次的 JGE .Next_ARDS MOV EDX, EAX ;EDX 保存了 Total Memory .Next_ARDS: ADD EBX, 0x14 ;继续判断下一个 LOOP .Find_Max_Memory JMP .Memory_Get_OK ;比较完成了 跳转到OK ; ; .E820_Fail_Try_E801: MOV AX, 0xe801 INT 0x15 JC .E801_Fail_Try_88 ;fail ;LOW 15MB MOV CX, 0x400 ;1KB MUL CX ;AX *= CX 高16位在DX中 低16位在AX中 SHL EDX, 16 ;*result High 16 AND EAX, 0x0000FFFF OR EDX, EAX ADD EDX, 0x10000 ;+1MB MOV ESI, EDX ;MoreThan 16MB MOV EAX, 0x0 MOV AX, BX MOV ECX, 0x10000 ;64kb MUL ECX MOV EDX, ESI JMP .Memory_Get_OK ; ; .E801_Fail_Try_88: MOV AH, 0x88 INT 0x15 JC .Error_HLT ;Error AND EAX, 0x0000FFFF MOV CX, 0x400 ;1kb MUL CX SHL EDX, 16 ;result high 16 OR EDX, EAX ADD EDX, 0x10000 ;1MB ; .Memory_Get_OK: MOV [Total_Memory_Bytes], EDX .Error_HLT: HLT4.获取到的内存的大小
可以看到获取到的内存的大小是32MB,和我们配置的环境一模一样



