ConstructMemoryDescriptors (startup.com)

 

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

转载于:https://my.oschina.net/fatboy/blog/401588

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值