Skip to content

Instantly share code, notes, and snippets.

@sunskyhsh
Created March 17, 2017 13:17
Show Gist options
  • Save sunskyhsh/559d3d2729e3dfb634797e41c9f9f2f5 to your computer and use it in GitHub Desktop.
Save sunskyhsh/559d3d2729e3dfb634797e41c9f9f2f5 to your computer and use it in GitHub Desktop.
# coding: utf-8
#
# This is a solution to
# https://chyyuu.gitbooks.io/os_course_exercises/content/all/04-1-spoc-discussion.html#虚拟页式存储的地址转换
#
# Author: github.com/sunskyhsh
import sys
def translate(va, pd):
print 'Virtual Address 0x%x:'%va
pdi = (va & 0x7c00) >> 10 # 0111 1100 0000 0000
pti = (va & 0x03e0) >> 5 # 0000 0011 1110 0000
offset = va & 0x1f # 0000 0000 0001 1111
addr = None
# read page directory entry
pde = pd[pdi]
pfn = pde & 0x7f
valid1 = (pde >> 7)
print ' --> pde index:0x%x'%pdi,'pde contents:(valid %d, pfn 0x%x)'%(valid1, pde&0x7f)
# read memory
with open('memory.txt','r') as f:
lines = f.readlines()
if not valid1:
with open('disk.txt','r') as f:
print ' --> Fault (page directory entry not valid)'
exit(1)
# read page table and page table entry
line = lines[pfn].split(':')
pt = map(lambda x: int(x, 16), line[1].split())
pte = pt[pti]
pfn = pte & 0x7f
valid2 = (pte >> 7)
print ' --> pte index:0x%x'%pti,'pte contents:(valid %d, pfn 0x%x)'%(valid1, pte&0x7f)
# not valid --> read disk
if not valid1 and valid2:
with open('disk.txt','r') as f:
lines = f.readlines()
# read value
line = lines[pfn].split(':')
value = map(lambda x: int(x, 16), line[1].split())[offset]
addr = (pfn<<5) + offset # '+' is priorer than '<<'
if addr:
if valid1 and valid2:
print ' --> To Physical address 0x%x'%addr, '--> Value: 0x%x'%value
else:
print ' --> To Disk sector address 0x%x'%addr, '--> Value: 0x%x'%value
def main():
pdb = 0xd80
# read page directory
with open('memory.txt','r') as f:
for line in f.readlines():
line = line.split(':')
if int(line[0].split(' ')[1], 16) == (pdb>>5):
pd = map(lambda x: int(x, 16), line[1].split())
break
if len(sys.argv) != 2:
va = raw_input('Please input 16 bits address (hexadecimal number): ')
va = int(va, 16)
elif len(sys.argv[1]) > 4:
print 'Error: wrong address.'
exit(1)
else:
va = int(sys.argv[1], 16)
translate(va, pd)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment