Exercise

Solidify your concepts and understanding by playing around with the simulator and finding the answer to the exercise questions provided in this lesson.

We'll cover the following

Simulator

This program allows you to see how address translations are performed in a system with segmentation. See the README for details.

#! /usr/bin/env python

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", "--addresses", default="-1",
                  help="a set of comma-separated pages to access; -1 means randomly generate", 
                  action="store", type="string", dest="addresses")
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", "--numaddrs", default=5,
                  help="number of virtual addresses to generate",
                  action="store", type="int", dest="num")
parser.add_option("-b", "--b0", default="-1",
                  help="value of segment 0 base register",
                  action="store", type="string", dest="base0")
parser.add_option("-l", "--l0", default="-1",
                  help="value of segment 0 limit register",
                  action="store", type="string", dest="len0")
parser.add_option("-B", "--b1", default="-1",
                  help="value of segment 1 base register",
                  action="store", type="string", dest="base1")
parser.add_option("-L", "--l1", default="-1",
                  help="value of segment 1 limit register",
                  action="store", type="string", dest="len1")
parser.add_option("-c", help="compute answers for me",
                  action="store_true", default=False, dest="solve")


(options, args) = parser.parse_args()

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)
addresses = str(options.addresses)

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
#
len0 = convert(options.len0)
len1 = convert(options.len1)
base0 = convert(options.base0)
base1 = convert(options.base1)

if len0 == -1:
    len0 = int(asize/4.0 + (asize/4.0 * random.random()))

if len1 == -1:
    len1 = int(asize/4.0 + (asize/4.0 * random.random()))

# now have to find room for them
if base0 == -1:
    done = 0
    while done == 0:
        base0 = int(psize * random.random())
        if (base0 + len0) < psize:
            done = 1

# internally, base1 points to the lower address, and base1+len1 the higher address
# (this differs from what the user would pass in, for example)
if base1 == -1:
    done = 0
    while done == 0:
        base1 = int(psize * random.random())
        if (base1 + len1) < psize:
            if (base1 > (base0 + len0)) or ((base1 + len1) < base0):
                done = 1
else:
    base1 = base1 - len1


if len0 > asize/2.0 or len1 > asize/2.0:
    print 'Error: length register is too large for this address space'
    exit(1)


print 'Segment register information:'
print ''
print '  Segment 0 base  (grows positive) : 0x%08x (decimal %d)' % (base0, base0)
print '  Segment 0 limit                  : %d' % (len0)
print ''
print '  Segment 1 base  (grows negative) : 0x%08x (decimal %d)' % (base1+len1, base1+len1)
print '  Segment 1 limit                  : %d' % (len1)
print ''
nbase1  = base1 + len1

if (len0 + base0) > (base1) and (base1 > base0):
    print 'Error: segments overlap in physical memory'
    exit(1)


addrList = []
if addresses == '-1':
    # need to generate addresses
    for i in range(0, options.num):
        n = int(asize * random.random())
        addrList.append(n)
else:
    addrList = addresses.split(',')

#
# now, need to generate virtual address trace
#
print 'Virtual Address Trace'
i = 0
for vStr in addrList:
    # vaddr = int(asize * random.random())
    vaddr = int(vStr)
    if vaddr < 0 or vaddr >= asize:
        print 'Error: virtual address %d cannot be generated in an address space of size %d' % (vaddr, asize)
        exit(1)
    if options.solve == False:
        print '  VA %2d: 0x%08x (decimal: %4d) --> PA or segmentation violation?' % (i, vaddr, vaddr)
    else:
        paddr = 0
        if (vaddr >= (asize / 2)):
            # seg 1
            paddr = nbase1 + (vaddr - asize)
            if paddr < base1:
                print '  VA %2d: 0x%08x (decimal: %4d) --> SEGMENTATION VIOLATION (SEG1)' % (i, vaddr, vaddr)
            else:
                print '  VA %2d: 0x%08x (decimal: %4d) --> VALID in SEG1: 0x%08x (decimal: %4d)' % (i, vaddr, vaddr, paddr, paddr)
        else:
            # seg 0
            if (vaddr >= len0):
                print '  VA %2d: 0x%08x (decimal: %4d) --> SEGMENTATION VIOLATION (SEG0)' % (i, vaddr, vaddr)
            else:
                paddr = vaddr + base0
                print '  VA %2d: 0x%08x (decimal: %4d) --> VALID in SEG0: 0x%08x (decimal: %4d)' % (i, vaddr, vaddr, paddr, paddr)
    i += 1

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 address space with two segments: the top'
    print 'bit of the virtual address can thus be used to check whether the virtual address'
    print 'is in segment 0 (topbit=0) or segment 1 (topbit=1). Note that the base/limit pairs'
    print 'given to you grow in different directions, depending on the segment, i.e., segment 0'
    print 'grows in the positive direction, whereas segment 1 in the negative. '
    print ''

Questions

  1. First let’s use a tiny address space to translate some addresses. Here’s a simple set of parameters with a few different random seeds; can you translate the addresses?

    segmentation.py -a 128 -p 512 -b 0 -l 20 -B 512 -L 20 -s 0

    segmentation.py -a 128 -p 512 -b 0 -l 20 -B 512 -L 20 -s 1

    segmentation.py -a 128 -p 512 -b 0 -l 20 -B 512 -L 20 -s 2

  2. Now, let’s see if we understand this tiny address space we’ve constructed (using the parameters from the question above). What is the highest legal virtual address in segment 0? What about the lowest legal virtual address in segment 1? What are the lowest and highest illegal addresses in this entire address space? Finally, how would you run segmentation.py with the -A flag to test if you are right?

  3. Let’s say we have a tiny 16-byte address space in a 128-byte physical memory. What base and bounds would you set up so as to get the simulator to generate the following translation results for the specified address stream: valid, valid, violation, …, violation, valid, valid? Assume the following parameters:

    segmentation.py -a 16 -p 128

    -A 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

    --b0 ? --l0 ? --b1 ? --l1?

  4. Assume we want to generate a problem where roughly 90% of the randomly-generated virtual addresses are valid (not segmentation violations). How should you configure the simulator to do so? Which parameters are important to getting this outcome?

  5. Can you run the simulator such that no virtual addresses are valid? How?

Get hands-on with 1400+ tech skills courses.