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