ConstructMemoryDescriptors的c语言描述代码
;ConstructMemoryDescriptors的c语言版本
BOOLEAN ConstructMemoryDescriptors(VOID)
{
ULONG StartAddr,EndAddr;
E820FRAME E820Frame;
MemoryDescriptorList->BlockSize = 0; //初始化首个链表为0
MemoryDescriptorList->BlockBase = 0; //初始化首个链表为0
//循环检测物理地址
do{
E820Frame.Size = sizeof(E820Frame.Descriptor);
Int15E820 (&E820Frame);
if (E820Frame.ErrorFlag || E820Frame.Size(sizeof(E820Frame.Descriptor)) //这里作者在书上的括号写错了
break;
//获取开始地址和结束地址
StartAddr = E820Frame.Descriptor.BaseAddrLow;
EndAddr = E820Frame.Descriptor.BaseAddrLow + E820Frame.Descriptor.SizeLow - 1;
//高于4G的内存并不使用
if(E820Frame.Descriptor.BaseAddrHigh == 0)
{
if(EndAddr < StartAddr)
{
//EndAddr 字长是4B 及32位 最多表示4G
//如果EndAddr < StartAddr 表示EndAddr溢出了直接设置为0xFFFFFFFF及4G
//终于晓得为啥子32位只支持4G寻址了
EndAddr = 0xFFFFFFF;
}
//仅需要内存类型为BiosMemoryUsable (1) 的内存
if(E820Frame.Descriptor.MemoryType==1)
{
//插入内存描述符链表
InsertDescriptor(StartAddr,EndAddr - StartAddr +1)
}
}
}while (E820Frame.Key); //如果key不等于0 说明还有内存块继续循环
return TRUE;
}
nasm版本代码;
;nasm实现方法
;BOOLEAN ConstructMemoryDescriptors (VOID);
ConstructMemoryDescriptors:
E820Frame.ErrorFlag equ -28h
E820Frame.Key equ -24h
E820Frame.Size equ -20h
E820Frame.Descriptor.BaseAddrLow equ -1Ch
E820Frame.Descriptor.BaseAddrHigh equ -18h
E820Frame.Descriptor.SizeLow equ -14h
E820Frame.Descriptor.MemoryType equ -0Ch
EndAddr equ -8
StartAddr equ -4
push ebp
mov ebp, esp
sub esp, 68h
push ebx
push esi
push edi
;(7000H * 10H) + 0 = 70000H
push es
push DESCRIPTOR_ADDRESS >> 4
pop es
mov eax, 0
mov dword[eax+MEMORY_DESCRIPTOR.BlockSize], 0
mov eax, MemoryDescriptorList
mov dword[eax+MEMORY_DESCRIPTOR.BlockBase], 0
mov dword[ebp+E820Frame.Key], 0
.loop:
mov dword[ebp+E820Frame.Size], E820FRAME_DESCRIPTOR_SIZE
lea eax, [ebp+E820Frame.ErrorFlag]
push eax
call Int15E820
add esp, 4
cmp dword[ebp+E820Frame.ErrorFlag], 0
jnz .breakA
cmp dword[ebp+E820Frame.Size], E820FRAME_DESCRIPTOR_SIZE
jnb .GotAddr
.breakA:
jmp .return
; ---------------------------------------------------------------------------
.GotAddr:
mov eax, [ebp+E820Frame.Descriptor.BaseAddrLow]
mov [ebp+StartAddr], eax
mov eax, [ebp+E820Frame.Descriptor.SizeLow]
mov ecx, [ebp+E820Frame.Descriptor.BaseAddrLow]
lea edx, [ecx+eax-1]
mov [ebp+EndAddr], edx
cmp dword[ebp+E820Frame.Descriptor.BaseAddrHigh], 0
jnz .next
mov eax, [ebp+EndAddr]
cmp eax, [ebp+StartAddr]
jnb .MemoryType
mov dword[ebp+EndAddr], 0FFFFFFFFh
.MemoryType:
cmp dword[ebp+E820Frame.Descriptor.MemoryType], 1
jnz .next
mov eax, [ebp+EndAddr]
sub eax, [ebp+StartAddr]
add eax, 1
push eax
mov ecx, [ebp+StartAddr]
push ecx
call InsertDescriptor
add esp, 8
.next:
cmp dword[ebp+E820Frame.Key], 0
jnz .loop
.return:
mov al, 1
pop es
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
retn
Int15E820:
push ebp
mov bp,sp
mov bp,[bp + 6]
push es
push edi
push esi
push ebx
push ss
pop es
mov ebx,[bp + E820FRAME.Key]
mov ecx,[bp + E820FRAME.Size]
lea di, [bp + E820FRAME.BaseAddrLow]
mov eax, 0E820h
mov edx, 'PAMS'
int 15h
mov [bp + E820FRAME.Key], ebx
mov [bp + E820FRAME.Size], ecx
sbb ecx, ecx
sub eax, 'PAMS'
or ecx, eax
mov [bp + E820FRAME.ErrorFlag],ecx
pop ebx
pop esi
pop edi
pop es
pop ebp
retn