MCS-284 Lab 2: More Advanced Assembly Language Programming

Due October 18, 2011

The goal of this lab is to practice more advanced assembly language programming skills, in particular, the use of stack frames to support recursion.

In particular, for the required portion of the project, you will write an assembly language program that generates a tree-recursive process for drawing a Sierpinski carpet on the bitmap display tool that is available within MARS. An example Sierpinski carpet is shown below. Once you have replicated this image, you can earn extra credit by exploring other fractals of your own choosing.
level 4 Sierpinski carpet

You are not required to submit a lab write up; instead, just email me your assembly language programs (one per fractal you choose to do). For any fractals other than the Sierpinski carpet, you might also want to include screen captures of the result. However, that isn't essential. You should be sure that your programs follow the conventions for such matters as which registers are used for arguments and which registers each procedure needs to leave as it found them. Use a comment block at the top of each procedure to describe how it would be used. Use other comments only when necessary to explain the higher-level purpose of a code block, as opposed to directly echoing the assembly language instructions.

The following is a Python version of the program you need to write; to produce the image shown above, this would be called as carpet(0, 0, 243, 4). Your main program can contain that procedure call and then use syscall 10 to exit.

def carpet(x0, y0, size, level):
    '''Draw a carpet with upper left corner at (x0,y0).
        The coordinate system has y increasing downward, not like usual math.
        The size specifies both the width and the height.
        If the level is 0, nothing should be drawn (leave background alone).'''
    if level != 0:
        newSize = size // 3
        newLevel = level - 1
        x1 = x0 + newSize
        x2 = x1 + newSize
        y1 = y0 + newSize
        y2 = y1 + newSize

        carpet(x0, y0, newSize, newLevel)
        carpet(x0, y1, newSize, newLevel)
        carpet(x0, y2, newSize, newLevel)

        carpet(x1, y0, newSize, newLevel)
        rectangle(x1, newSize, y1, newSize) # fill middle block solidly
        carpet(x1, y2, newSize, newLevel)

        carpet(x2, y0, newSize, newLevel)
        carpet(x2, y1, newSize, newLevel)
        carpet(x2, y2, newSize, newLevel)

def rectangle(x, width, y, height):
    '''Fill a rectangle with upper left corner at (x,y) and specified sizes.'''
    # I am not providing Python code for this procedure.
    # I am, however, providing an assembly language version.
    # You don't really need to understand the assembly language version,
    # aside from what arguments need to be passed into it.
    # It works by storing into the memory region occupied by the bitmap display,
    # that is, the frame buffer.

You can copy the assembly language version of the rectangle procedure out of the example program rectangle.asm that I have linked to this lab assignment. This example program simply draws a single rectangle and then exits.

The following list provides some suggestions for extra-credit variations. Feel free to pick any that suit you. Or fee free to come up with something of your own.