Objectives

  • Understand exception and interrupt handling in MIPS

  • Learn how to write exception handlers in MIPS.

Exercise 1: (Exception types)

Run the following sample code in MARS, then answer the questions below.

   .text
   .globl main  
main:
  li $t0, 2147483647   #
  li $t1, 5000
  add $a0, $t0, $t1    #

  li $v0, 10           # exit
  syscall
  1. What is the value (in hexadecimal) of the status register of coprocessor 0?

  2. What is the value (in hexadecimal) of the cause register of coprocessor 0?

  3. What type of exception occurred?

  4. At what address (in hexadecimal) did the exception occur?

Exercise 2 : (Interrupts)

Enabling interrupts on a MIPS processor is a two-step process:

  • Configure the device in question to send interrupt signals This usually requires setting an interrupt enable bit in a control register in the device.

  • Configure coprocessor 0 to accept interrupt signals This is done by setting bit 0 of the status register ($12) to enable interrupts globally, and then setting specific bits in the status register to enable specific interrupts. Bits 8 through 15 of the status register allow for 8 different levels of interrupts. For example, bits 3 and 4 of the mask (bits 11 and 12 of the status register) enable keyboard and display interrupts, respectively.

If we wanted to enable all interrupts in MIPS, complete the bitmask for the ori instruction:

   mfc0    $s1, $12         # read into $s1 the contents of the status register  
   ori     $s1, _________   # <<<<< to compete
   mtc0    $s1, $12         # update of the contents of the status register

If we wanted to enable only the keyboard and display interrupts, complete the bitmask for the ori instruction:

   mfc0    $s1, $12         # # read into $s1 the contents of the status register 
   ori     $s1, _________   # <<<<< to compete
   mtc0    $s1, $12         # update of the contents of the status register

Exercise 3: (Exception handler)

An exception handler must report the address of the instruction that caused the exception, the exception code, and must resume (or terminate) program execution after handling the exception.

  1. For this exercise, we will use a custom exception handler instead of the one that is already built into MARS. To install our exception handler, follow these instructions:

    1. Begin by downloading the starter file available at the top of this document. The file (exceptions_handler.s) is a custom MIPS exception handler.

    2. In MARS, click to unroll “Settings” from the menu
      Mars exception handler

    3. Check the box “Initialize Program Counter to global ‘main’ if defined”

    4. unroll again the “Settings” menu and click on “Exception Handler”. A new dialog box will appear Mars exception handler 2

    5. Check the box “Include this exception handler file in all assemble operations”, then enter the path to the exception handler file you downloaded. Choose OK to finish.

    6. MARS is now configured to use our new exception handler instead of the built-in handler.

  2. In the MARS editor, write a program including instructions that cause: overflow, accesses to invalid memory addresses, trap instructions, and breakpoint instructions. Your program must start with this two lines of code:

    .globl
    main:
    
  3. Modify the exception handler to display the invalid vaddr when the exception is caused by a load, store, or instruction fetch (i.e. exception code 4 or 5). Test your exception handler by writing load and store instructions that generate invalid memory addresses.

  4. Using memory-mapped I/O and polling (cf. «  Exception mechanisms in MIPS »), write a function print_string that prints a string to the screen without using any system calls (i.e., do not use syscall instructions). The address of the string is passed in the register $a0 and the string must be terminated by the NUL (i.e. zero) character. Test this function by calling it from the main function. Make sure to enable the MMIO keyboard and display simulator from the menu (Tools | Keyboard and Display MMIO Simulator) and connect this simulator to MARS by clicking the « Connect to MIPS » button.

  5. Still using memory-mapped I/O and polling, write a program that reads characters directly from the keyboard (cf. «  Exception mechanisms in MIPS »). To demonstrate how slow the keyboard is, print the character entered and the number of iterations after exiting the wait_keyboard loop. Repeat the execution of the program until you press the (Return) key on the keyboard. Make sure to run the MARS simulator at maximum speed.

  6. If the keyboard interrupt enable bit is set, the keyboard will interrupt the processor every time a key is pressed. Write a simple interrupt handler that returns the entered character to the $v0 register. Rewrite the main function from question #4 using keyboard interrupts.

  7. Using memory-mapped I/O and polling, write a read_string function that reads a string directly from the keyboard. The function will retrieve the characters from the keyboard and store them in an array pointed to by the $a0 register. The function should continue until n-1 characters are read or the newline character is received (i.e. (Return) key is pressed). The n parameter should be passed in the $a1 register. The function should insert a NUL byte at the end of the string and should return the actual number of characters read in $v0 register. Make sure to enable the MMIO Keyboard and Display Simulator and connect the simulator to Mars. Write a main function to test read_string multiple times and to display the string after each call.