Writing and Using MIPS Exception Handlers in MARS
Writing and Using MIPS Exception Handlers in MARS
Writing and Using MIPS Exception Handlers in MARS
Exception handlers, also known as trap handlers or interrupt handlers, can easily be incorporated into a MIPS program. This guide is not intended to be comprehensive but provides the essential information for writing and using exception handlers. Although the same mechanism services all three, exceptions, traps and interrupts are all distinct from each other. Exceptions are caused by exceptional conditions that occur at runtime such as invalid memory address references. Traps are caused by instructions constructed especially for this purpose, listed below. Interrupts are caused by external devices. MARS partially but not completely implements the exception and interrupt mechanism of SPIM.
Essential Facts
Some essential facts about writing and using exception handlers include:
MARS simulates basic elements of the MIPS32 exception mechanism. The MIPS instruction set includes a number of instructions that conditionally trigger a trap exception based on the relative values of two registers or of a constant and a register: teq, teqi (trap if equal), tne, tnei (trap if not equal), tge, tgeu, tgei, tgeiu (trap if greater than or equal), tlt, tltu, tlti, tltiu (trap if less than) When an exception occurs, 1. Coprocessor 0 register $12 (status) bit 1 is set 2. Coprocessor 0 register $13 (cause) bits 2-6 are set to the exception type (codes below) 3. Coprocessor 0 register $14 (epc) is set to the address of the instruction that triggered the exception 4. If the exception was caused by an invalid memory address, Coprocessor 0 register $8 (vaddr) is set to the invalid address. 5. Execution flow jumps to the MIPS instruction at memory location 0x800000180. This address in the kernel text segment (.ktext directive) is the standard MIPS32 exception handler location. The only way to change it in MARS is to change the MIPS memory configuration through the Settings menu item Memory Configuration. There are three ways to include an exception handler in a MIPS program 1. Write the exception handler in the same file as the regular program. An example of this is presented below. 2. Write the exception handler in a separate file, store that file in the same directory as the regular program, and select the Settings menu item "Assemble all files in directory"
3. Write the exception handler in a separate file, store that file in any directory, then open the "Exception Handler..." dialog in the Settings menu, check the check box and browse to that file. If there is no instruction at location 0x800000180, MARS will terminate the MIPS program with an appropriate error message. The exception handler can return control to the program using the eret instruction. This will place the EPC register $14 value into the Program Counter, so be sure to increment $14 by 4 before returning to skip over the instruction that caused the exception. The mfc0 and mtc0 instructions are used to read from and write to Coprocessor 0 registers. Bits 8-15 of the Cause register $13 can also be used to indicate pending interrupts. Currently this is used only by the Keyboard and Display Simulator Tool, where bit 8 represents a keyboard interrupt and bit 9 represents a display interrupt. For more details, see the Help panel for that Tool. Exception types declared in mars.simulator.Exceptions, but not necessarily implemented, are ADDRESS_EXCEPTION_LOAD (4), ADDRESS_EXCEPTION_STORE (5), SYSCALL_EXCEPTION (8), BREAKPOINT_EXCEPTION (9), RESERVED_INSTRUCTION_EXCEPTION (10), ARITHMETIC_OVERFLOW_EXCEPTION (12), TRAP_EXCEPTION(13), DIVIDE_BY_ZERO_EXCEPTION (15), FLOATING_POINT_OVERFLOW (16), and FLOATING_POINT_UNDERFLOW (17). When writing a non-trivial exception handler, your handler must first save general purpose register contents, then restore them before returning.
# Trap handler in the standard MIPS32 kernel text segment .ktext 0x80000180 move $k0,$v0 # Save $v0 value move $k1,$a0 # Save $a0 value la $a0, msg # address of string to print li $v0, 4 # Print String service syscall move $v0,$k0 # Restore $v0 move $a0,$k1 # Restore $a0 mfc0 $k0,$14 # Coprocessor 0 register $14 has address of trapping instruction addi $k0,$k0,4 # Add 4 to point to next instruction mtc0 $k0,$14 # Store new address back into $14 eret # Error return; set PC to value in $14
10 11 12 $a0 = address of nullterminated string containing filename $a1 = flags $a2 = mode $a0 = character to print See note below table $v0 contains character read $v0 contains file descriptor (negative if error). See note below table
open file
13
14
$a0 = file descriptor $a1 = address of input $v0 contains number of characters read (0 if buffer end-of-file, negative if error). See note below $a2 = maximum number table of characters to read $a0 = file descriptor $a1 = address of output buffer $a2 = number of characters to write $a0 = file descriptor $a0 = termination result See note below table $v0 contains number of characters written (negative if error). See note below table
write to file
15
16 17
Services 1 through 17 are compatible with the SPIM simulator, other than Open File (13) as described in the Notes below the table. Services 30 and higher are exclusive to MARS. time (system time) 30 $a0 = low order 32 bits of system time $a1 = high order 32 bits of system time. See note below table $a0 = pitch (0-127) $a1 = duration in Generate tone and return immediately. See milliseconds note below table $a2 = instrument (0-127) $a3 = volume (0-127) $a0 = the length of time to sleep in milliseconds. Causes the MARS Java thread to sleep for (at least) the specified number of milliseconds. This timing will not be precise, as the Java implementation will add some overhead.
MIDI out
31
sleep
32
$a0 = pitch (0-127) $a1 = duration in Generate tone and return upon tone milliseconds completion. See note below table $a2 = instrument (0-127) $a3 = volume (0-127) $a0 = integer to print Displayed value is 8 hexadecimal digits, leftpadding with zeroes if necessary.
34
Displayed value is 32 bits, left-padding with zeroes if necessary. Displayed as unsigned decimal value.
set seed
40
$a0 = i.d. of pseudorandom number generator (any int). $a1 = seed for corresponding pseudorandom number generator. $a0 = i.d. of pseudorandom number generator (any int). $a0 = i.d. of pseudorandom number generator (any int). $a1 = upper bound of range of returned values. $a0 = i.d. of pseudorandom number generator (any int). $a0 = i.d. of pseudorandom number generator (any int).
No values are returned. Sets the seed of the corresponding underlying Java pseudorandom number generator (java.util.Random). See note below table $a0 contains the next pseudorandom, uniformly distributed int value from this random number generator's sequence. See note below table $a0 contains pseudorandom, uniformly distributed int value in the range 0 <= [int] < [upper bound], drawn from this random number generator's sequence. See note below table $f0 contains the next pseudorandom, uniformly distributed float value in the range 0.0 <= f < 1.0 from this random number generator's sequence. See note below table $f0 contains the next pseudorandom, uniformly distributed double value in the range 0.0 <= f < 1.0 from this random number generator's sequence. See note below table
random int
41
42
random float
43
44 45-49 50
$a0 contains value of user-chosen option $a0 = address of null0: Yes terminated string that is 1: No the message to user 2: Cancel $a0 contains int read $a1 contains status value $a0 = address of null0: OK status terminated string that is -1: input data cannot be correctly parsed the message to user -2: Cancel was chosen -3: OK was chosen but no data had been input into field $a0 = address of null$f0 contains float read terminated string that is $a1 contains status value the message to user 0: OK status
InputDialogInt
51
InputDialogFloat
52
-1: input data cannot be correctly parsed -2: Cancel was chosen -3: OK was chosen but no data had been input into field $f0 contains double read $a1 contains status value $a0 = address of null0: OK status terminated string that is -1: input data cannot be correctly parsed the message to user -2: Cancel was chosen -3: OK was chosen but no data had been input into field See Service 8 note below table $a1 contains status value $a0 = address of null0: OK status. Buffer contains the input string. terminated string that is -2: Cancel was chosen. No change to buffer. the message to user -3: OK was chosen but no data had been input $a1 = address of input into field. No change to buffer. buffer -4: length of the input string exceeded the $a2 = maximum number specified maximum. Buffer contains the of characters to read maximum allowable input string plus a terminating null. $a0 = address of nullterminated string that is the message to user $a1 = the type of message to be displayed: 0: error message, indicated by Error icon 1: information message, indicated by Information N/A icon 2: warning message, indicated by Warning icon 3: question message, indicated by Question icon other: plain message (no icon displayed) $a0 = address of nullterminated string that is an information-type message to user N/A $a1 = int value to display in string form after the first string
InputDialogDouble
53
InputDialogString
54
MessageDialog
55
MessageDialogInt
56
MessageDialogFloat
57
$a0 = address of nullterminated string that is an information-type message to user N/A $f12 = float value to display in string form after the first string $a0 = address of nullterminated string that is an information-type message to user N/A $f12 = double value to display in string form after the first string $a0 = address of nullterminated string that is an information-type message to user N/A $a1 = address of nullterminated string to display after the first string
MessageDialogDouble 58
MessageDialogString
59
NOTES: Services numbered 30 and higher are not provided by SPIM Service 8 - Follows semantics of UNIX 'fgets'. For specified length n, string can be no longer than n-1. If less than that, adds newline to end. In either case, then pads with null byte If n = 1, input is ignored and null byte placed at buffer address. If n < 1, input is ignored and nothing is written to the buffer. Service 11 - Prints ASCII character corresponding to contents of low-order byte. Service 13 - MARS implements three flag values: 0 for read-only, 1 for write-only with create, and 9 for write-only with create and append. It ignores mode. The returned file descriptor will be negative if the operation failed. The underlying file I/O implementation uses java.io.FileInputStream.read() to read and java.io.FileOutputStream.write() to write. MARS maintains file descriptors internally and allocates them starting with 0. Services 13,14,15 - In MARS 3.7, the result register was changed to $v0 for SPIM compatability. It was previously $a0 as erroneously printed in Appendix B of Computer Organization and Design,. Service 17 - If the MIPS program is run under control of the MARS graphical interface (GUI), the exit code in $a0 is ignored. Service 30 - System time comes from java.util.Date.getTime() as milliseconds since 1 January 1970. Services 31,33 - Simulate MIDI output through sound card. Details below. Services 40-44 use underlying Java pseudorandom number generators provided by the java.util.Random class. Each stream (identified by $a0 contents) is modeled by a different Random
object. There are no default seed values, so use the Set Seed service (40) if replicated random sequences are desired.
Service 31 will generate the tone then immediately return. Service 33 will generate the tone then sleep for the tone's duration before returning. Thus it essentially combines services 31 and 32. This service requires four parameters as follows:
pitch ($a0)
Accepts a positive byte value (0-127) that denotes a pitch as it would be represented in MIDI Each number is one semitone / half-step in the chromatic scale. 0 represents a very low C and 127 represents a very high G (a standard 88 key piano begins at 9A and ends at 108-C). If the parameter value is outside this range, it applies a default value 60 which is the same as middle C on a piano. From middle C, all other pitches in the octave are as follows: 61 = C# or Db 62 = D 63 = D# or Eb 64 = E or Fb 65 = E# or F 66 = F# or Gb 67 = G 68 = G# or Ab 69 = A 70 = A# or Bb 71 = B or Cb 72 = B# or C
instrument ($a2)
Accepts a positive byte value (0-127) that denotes the General MIDI "patch" used to play the tone. If the parameter is outside this range, it applies a default value 0 which is an Acoustic Grand Piano. General MIDI standardizes the number associated with each possible instrument (often referred to as program change numbers), however it does not determine how the tone will sound. This is determined by the synthesizer that is producing the sound. Thus a Tuba (patch 58) on one computer may sound different than that same patch on another computer. The 128 available patches are divided into instrument families of 8:
Note that outside of Java, General MIDI usually refers to patches 1-128. When referring to a list of General MIDI patches, 1 must be subtracted to play the correct patch. For a full list of General MIDI instruments, see www.midi.org/about-midi/gm/gm1sound.shtml. The General MIDI channel 10 percussion key map is not relevant to the toneGenerator method because it always defaults to MIDI channel 1.
volume ($a3)
Accepts a positive byte value (0-127) where 127 is the loudest and 0 is silent. This value denotes MIDI velocity which refers to the initial attack of the tone. If the parameter value is outside this range, it applies a default value 100. MIDI velocity measures how hard a note on (or note off) message is played, perhaps on a MIDI controller like a keyboard. Most MIDI synthesizers will translate this into volume on a logarithmic scale in which the difference in amplitude decreases as the velocity value increases. Note that velocity value on more sophisticated synthesizers can also affect the timbre of the tone (as most instruments sound different when they are played louder or softer).
System service 31 was developed and documented by Otterbein student Tony Brock in July 2007.