I have the following program that reads a character and prints it:
.macro print_char
li $v0, 11
lbu $a0, ($s0)
syscall
.end_macro
.macro read_char
li $v0, 12
syscall
sb $v0, ($s0)
.end_macro
.text
# Initialize registers.
li $s0, 0x10010000
li $t0, 0x0
read_char
print_char
It works in the MARS MIPS IDE, I can press the Enter
key and the simulator will print a newline. But when I try to do the same thing using the MARS MIPS CLI, it returns an invalid char input (syscall 12)
error. Why is this?
The following code contains an exception handler, that handles the exception on the bad input for syscall #12, then changes the 0xc to 0xd; advances the exception pc (epc) and resumes the user code:
.macro print_char
li $v0, 11
lbu $a0, ($s0)
syscall
.end_macro
.macro read_char
li $v0, 12
syscall
sb $v0, ($s0)
.end_macro
.text
# Initialize registers.
li $s0, 0x10010000
li $t0, 0x0
read_char
print_char
li $v0, 10
syscall # terminate program
.ktext 0x80000180 # install this next code as kernel exception handler
li $v0, 0xd # change 0xc in $v0 to 0xd
mfc0 $k1, $14 # fetch epc (address of the offending syscall)
addi $k1, $k1, 4 # advance to next instruction
mtc0 $k1, $14 # update epc
eret # resume user code
Note that this handler has absolutely no error checking — in particular, it assumes that the only reason it might be invoked is to handle that syscall #12 error.