Lab 3

The WOOKIE Simulator

Introduction

The Axiom boards have several useful built-in debugging tools that should be familiar to you by now. You may have noticed, though, that there are some limitations with these tools. For example, what if your program is complex enough and you need to set more than 4 (BUFFALO) breakpoints to debug it. Or what if you need to set a breakpoint within a subroutine, this also is not allowed by the debug monitors. How then, can you see what is going on in the machine? In addition to these problems, it can be inconvenient (or impossible) to look at several different areas of memory during execution to track down an error in a program. What should you do? Write programs with no subroutines? Always write perfect code? Not likely! Instead, you can use some new external tools. Logic analyzers and in-line emulators can be invaluable for these types of problems, but first there is a simpler way that we will explore during this lab, the software simulator.

A software simulator is simply a program that runs on a PC. Its task is to act just like a MC68HC11 micro-controller. The simulator has the same registers, and memory as the real MC68HC11, but instead of the debug monitor (BUFFALO) you get something much better. The simulator allows you to view simultaneously different areas of memory and all of the registers, all while you step through program execution. You can see the entire picture. What's more, there are no limitations concerning the number of breakpoints.

The simulator you will use in the lab is called WOOKIE. On the lab PCs it can be found in the EE218\WOOKIE directory. A complete manual is available in the lab for your reference, and a short manual is included at the end of this lab. The short manual covers everything you will need for the laboratory exercises, but you are encouraged to study further. This simulator could be very useful to you from this point forward in the class. You can debug your programs before the lab, which saves you time and effort.

While you are getting accustomed to the simulator, you need some programs to work with. Since you may have been frustrated in the past with BUFFALO's problems related to the subroutines, let's take this opportunity to watch how the simulator deals with them.

Each program in this lab will use subroutines. A subroutine typically needs some input information to process and return some output information. We refer to this information as arguments or parameters. Inputs are passed in as parameters and results are passed back out as parameters. There are several ways to accomplish this, including:

  • Registers - simply put the values to pass in the registers .

  • Memory 1ocations - store parameters in certain absolute memory locations.

  • Stack - push the data onto the stack for retrieval on the other end.

You have used the first two methods already in previous labs, so this time you will use the stack to pass parameters. This is a more general method that does not have the limitations of the first two. It works as follows: before the subroutine call, push all the data the subroutine will need onto the stack. If you want to pass pointers to data, remember that the stack can hold addresses as well as data. Inside the subroutine, pull the data off of the stack and process it. When finished, push the ‘answers’ onto the stack and return. The calling program should retrieve the ‘answers’ from the stack and continue. The challenge is keeping up with the state of the stack and the order of the pushes and pulls. Don't forget that JSR and RTS have their own effect on the stack.

Before the Lab

Read the manual on the Wookie simulator. Next, read it again. Take notes. Make SURE you are familiar with and are prepared to use the following facilities:

  • Loading your code into the simulator.

  • Displaying/Modifying memory contents.

  • Displaying/Modifying registers contents.

  • Running your program and stepping through it.

  • Skipping and stepping through subroutines.

  • Setting, clearing, and displaying breakpoints.

Write programs to do the following:

  1. A list of eight numbers (unsigned, 8 bit) is in memory. The ninth number in the list represents a power of two by which all the rest of the numbers in the list should be raised. Write a program to multiply each number in the list by two to the specified power, leaving the results where the inputs were. Keep in mind that to multiply a binary number by two, you just shift it once to the left. Use a subroutine to perform the multiplication. Pass parameters in the A and X registers (A holds power of two and X points to the number to multiply). Since the results are in the same position as the inputs, they must be 8 bit. This means we cannot work with very large numbers, can we? Construct your data set so that overflow is not a problem. Your subroutine does not have to check for it.

  2. Given the same list of numbers, treat the power of two as a signed number (2's comp.). If the power is negative, divide by the absolute value of the power of two. In other words, if the ninth number was $FC, then divide by two to the third power ($FC=-4, so divide by two, four times). If the power is positive, the program should behave exactly as the first program.

  3. Write a program to calculate the mean of the numbers generated by the second program.

  4. Write a subroutine that will multiply two 8 bit binary numbers. You CANNOT use the MUL assembly instruction. An algorithm for this multiply has been thoroughly discussed in class and is covered in your text. Be sure you understand this algorithm before you use it. Be prepared to explain your code to the TA. Use the stack to pass parameters to and from the subroutine. Two single bytes are the input and two bytes (one 16 bit number) are the output. Your main program should push the data, call the subroutine, and then retrieve the answer from the stack. Meanwhile, the subroutine should retrieve the input numbers from the stack and push the answer back before it returns. Note carefully the description of the JSR and RTS instructions and their effect on the stack before you use the stack in a subroutine. There are some adjustments you must make. To make testing easier, have your main program read the input numbers from memory and store the results back in memory after the multiply.

Programming note: On the HC11-VDK Axiom board you terminate a program with SWI. This causes the monitor to jump up and take control. The BUFFALO monitor is not in the simulator (unless you load it, remember it's a program too) so you cannot get to it with an SWI. To terminate a program without the debug monitor, you should put an endless loop like the following:

... ... (program)
... ... (last line of program
SELF BRA SELF * INFINITE LOOP

If you let the simulator run to completion, it will just 'hang' at this instruction. You should, when using the simulator, put a breakpoint on SELF to get the same effect as SWI.

A word on testing - You, the engineer, are responsible for testing your own program to ensure that it meets all of the specifications. A single, casual test is usually not sufficient. Create data sets for testing that will exercise the full range of the program’s capabilities. If a specification has upper and lower limits, test your program at those limits. For example, will your ‘find the length of the list’ program from lab 2 work if the list length is zero? What if it is one? What if it is 256? You must test all cases. For this lab, determine what the limits are for each program. Create a data set to test the programs to these limits. Predict the results. Have the data with answers ready before the lab so you can be productive when you are ready to test.

Materials for lab - Bring the following items with you to lab:

  • A diskette with the above programs typed and ready for assembly.

  • Written program limitations and test data sets with answers.

  • The program from lab one that fills an area of memory (on disk).

  • A blank diskette to get your copy of the AS11 assembler (if needed).

In the Lab

Assemble your programs on the PCs in the lab using the AS11.EXE (Motorola's freeware assembler). This produces the data needed by the Wookie simulator. Be sure that you have selected the listing option for the assembler. An example for doing that is (DOS):

C:\> as11 -lo filename.asm

After assembly, verify that the .s19 and .lst files are present on disk.

Keep in mind that the simulator only sees these files, not the source code. Wookie provides the facility of watching target source code being executed. Wookie displays source code or disassembled object code. This feature is based on the presence, or absence respectively, of an AS11 formatted list file ending with the “lst” extension. If the “lst” file is present then Wookie will display source code extracted from that file, if there is no “lst” file in the current directory Wookie will display disassembled code from the “s19” file.

Start the simulator with the program from Lab 1:

C:\> Wookie

Load the program file, prg1.s19 using the Wookie GUI. Follow the steps given in the Wookie manual to execute/simulate the program. Open the windows for displaying ports, memory, CPU registers and observe the changes as you trace/step through the program (pressing the walking-man button). Continue exploring until you understand how to use the simulator.

Load and run your first program for this lab. Display the memory that holds your list of numbers. Also display the local storage areas in your subroutine, and the content of the stack. By the way, where is the stack? Who put it there? Is this where it is on the Axiom board? Can we move it? How? Single step your program through the first number raised to a power. What happens to the stack when the JSR instruction is executed? What happens on RTS? Debug your program (if necessary) and run your test cases. Verify the results.

Load and run the second program. Set a breakpoint inside the subroutine at the point you decide between multiplying and dividing. Is everything working right? Run your test cases and verify the results.

Load and run the third program.

Load and run the fourth program. Record (draw a diagram) of the stack at the following points for one subroutine call:

  1. before the parameter push

  2. before the subroutine call

  3. after the subroutine call

  4. after the subroutine pulls the parameters

  5. after the subroutine pushes the result

  6. before the RTS

  7. after the RTS

  8. after the main retrieves the result

Record the memory contents and addresses, and the value of the stack pointer at each point. Run your test data and verify the results.

After the Lab

Produce clean and well commented listing of the code you used in the lab. Provide a table of the test data sets and results and describe the rationale behind the testing (i.e. why did you choose these numbers?). Answer briefly the following questions:

  1. What are the benefits of a simulation vs. a 'real' MC68HC11?  What are the disadvantages?

  2. Can you compare BUFFALO and Wookie? Are they different?

  3. Can you use the PDATA routine from Lab 1 on the simulator? Why or why not?

  4. In your C programming class you learned about pass-by-value vs. pass-by-reference for subroutine arguments. Which method did you use for program four? What about program two? Can you use the stack for both methods?

  5. How could you modify programs one and two to deal with the overflow problem? Assume the word size must remain 8 bits.

  6. What are the limitations of the three different methods of parameter passing? Why would you want to use one over the other?

  7. How is the stack initialized on the Axiom board? How is it initialized in the simulator? Where is the 'system,' stack on the simulator?


| EE-218  Homepage | Syllabus | Schedule | Lab News | Faculty | Contact Information | Lab Info | Project |


Department of Electrical Engineering and Computer Science
Box 1824 Station B
Nashville, TN 37235
Phone: 322-2771
Fax: 343-6702


 | Search | Site Index | People Finder | Phone Directory | VUnet | VUmail | VU Library | Help |


Last Updated: Thursday, February 02, 2006

Turker Keskinpala

Copyright © 2003 Vanderbilt University