20 分页:更小的表

  1. VPN = (VirtualAddress &VPN_MASK) >> SHIFT;
  2. (Success, TlbEntry) = TLB_Lookup(VPN);
  3. if (Success == True) {// TLB Hit
  4. if (CanAccess(TlbEntry.ProtectBits) == True) {
  5. Offset = VirtualAddress & OFFSET_MASK;
  6. PhysAddr = (TlbEntry.PFN << SHIFT) | Offset;
  7. Register = AccessMemory(PhysAddr);
  8. } else {
  9. RaiseException(PROTECTION_FAULT)
  10. }
  11. } else { // TLB Miss
  12. // first, get page directory entry
  13. PDIndex = (VPN & PD_MASK) >> PD_SHIFT;
  14. PDEAddr = PDBR + (PDIndex * sizeof(PDE));
  15. PDE = AccessMemory(PDEAddr);
  16. }
  17. if (PDE.Valid == False) {
  18. RaiseException(SEGMENTATION_FAULT);
  19. } else { // PDE is valid: now fetch PTE from page table
  20. PTIndex = (VPN & PT_MASK) >> PT_SHIFT;
  21. PTEAddr = (PDE.PFN << SHIFT) + (PTIndex * sizeof(PTE));
  22. PTE = AccessMemory(PTEAddr);
  23. }
  24. if (PTE.Valid == False) {
  25. RaiseException(SEGMENTATION_FAULT);
  26. } else if (CanAccess(PTE.ProtectBits) == False) {
  27. RaiseException(PROTECTION_FAULT);
  28. } else {
  29. TLB_Insert(VPN, PTE.PFN, PTE.ProtectBits);
  30. RetryInstruction();
  31. }