此博客处内容为 《操作系统导论》(Operating Systems: Three Easy Pieces)第16章(分段) 作业习题程序说明。
原书英文版地址 https://pages.cs.wisc.edu/~remzi/OSTEP/
第8章 作业习题程序说明链接:https://blog.csdn.net/cai1149735196/article/details/115241018
第7章 作业习题程序说明链接:https://blog.csdn.net/cai1149735196/article/details/115208047
程序 relocation.py 让你看到,在带有基址和边界寄存器的系统中,如何执行地址转换。
这个程序允许你看到地址转换是如何在一个有基址和边界寄存器的系统中执行的。
与前面一样,运行程序需要两个步骤来测试您对基数和边界的理解。
首先,在不带-c标志的情况下运行,生成一组转换,看看自己能否正确地执行地址转换。完成后,使用-c标志运行以检查答案。
在这个作业中,假定一个与标准地址空间稍有不同的地址空间,在地址空间的两端分别有堆和栈。相反,我们将假设地址空间有一个代码段,然后是一个固定大小(小)的堆栈,然后是一个向下增长的堆,如下图所示。在这种配置中,只有一个增长方向,指向地址空间的更高区域。
-------------- 0KB
| Code |
-------------- 2KB
| Stack |
-------------- 4KB
| Heap |
| | |
| v |
-------------- 7KB
| (free) |
| ... |
在图中,边界寄存器将被设置为7~KB,因为这表示地址空间的结束。引用边界内的任何地址将被认为是合法的;超过这个值的引用是越界的,因此硬件会引发异常。要使用默认标志运行,请在命令行输入relocation.py。结果应该是这样的
python relocation.py
relocation.py代码如下
# python3
# relocation.py 代码
import sys
from optparse import OptionParser
import random
import math
def convert(size):
length = len(size)
lastchar = size[length-1]
if (lastchar == 'k') or (lastchar == 'K'):
m = 1024
nsize = int(size[0:length-1]) * m
elif (lastchar == 'm') or (lastchar == 'M'):
m = 1024*1024
nsize = int(size[0:length-1]) * m
elif (lastchar == 'g') or (lastchar == 'G'):
m = 1024*1024*1024
nsize = int(size[0:length-1]) * m
else:
nsize = int(size)
return nsize
#
# main program
#
parser = OptionParser()
parser.add_option('-s', '--seed', default=0, help='the random seed', action='store', type='int', dest='seed')
parser.add_option('-a', '--asize', default='1k', help='address space size (e.g., 16, 64k, 32m, 1g)', action='store', type='string', dest='asize')
parser.add_option('-p', '--physmem', default='16k', help='physical memory size (e.g., 16, 64k, 32m, 1g)', action='store', type='string', dest='psize')
parser.add_option('-n', '--addresses', default=5, help='number of virtual addresses to generate', action='store', type='int', dest='num')
parser.add_option('-b', '--b', default='-1', help='value of base register', action='store', type='string', dest='base')
parser.add_option('-l', '--l', default='-1', help='value of limit register', action='store', type='string', dest='limit')
parser.add_option('-c', '--compute', default=False, help='compute answers for me', action='store_true', dest='solve')
(options, args) = parser.parse_args()
print('')
print('ARG seed', options.seed)
print('ARG address space size', options.asize)
print('ARG phys mem size', options.psize)
print('')
random.seed(options.seed)
asize = convert(options.asize)
psize = convert(options.psize)
if psize <= 1:
print('Error: must specify a non-zero physical memory size.')
exit(1)
if asize == 0:
print('Error: must specify a non-zero address-space size.')
exit(1)
if psize <= asize:
print('Error: physical memory size must be GREATER than address space size (for this simulation)')
exit(1)
#
# need to generate base, bounds for segment registers
#
limit = convert(options.limit)
base = convert(options.base)
if limit == -1:
limit = int(asize/4.0 + (asize/4.0 * random.random()))
# now have to find room for them
if base == -1:
done = 0
while done == 0:
base = int(psize * random.random())
if (base + limit) < psize:
done = 1
print('Base-and-Bounds register information:')
print('')
print(' Base : 0x%08x (decimal %d)' % (base, base))
print(' Limit : %d' % (limit))
print('')
if base + limit > psize:
print('Error: address space does not fit into physical memory with those base/bounds values.')
print('Base + Limit:', base + limit, ' Psize:', psize)
exit(1)
#
# now, need to generate virtual address trace
#
print('Virtual Address Trace')
for i in range(0,options.num):
vaddr = int(asize * random.random())
if options.solve == False:
print(' VA %2d: 0x%08x (decimal: %4d) --> PA or segmentation violation?' % (i, vaddr, vaddr))
else:
paddr = 0
if (vaddr >= limit):
print(' VA %2d: 0x%08x (decimal: %4d) --> SEGMENTATION VIOLATION' % (i, vaddr, vaddr))
else:
paddr = vaddr + base
print(' VA %2d: 0x%08x (decimal: %4d) --> VALID: 0x%08x (decimal: %4d)' % (i, vaddr, vaddr, paddr, paddr))
print('')
if options.solve == False:
print('For each virtual address, either write down the physical address it translates to')
print('OR write down that it is an out-of-bounds address (a segmentation violation). For')
print('this problem, you should assume a simple virtual address space of a given size.')
print('')