mipsy
mipsy copied to clipboard
uninitialised memory access error should print values involved.
Example Code
.data
flag:
.byte '#', '#', '#', '#', '#', '.', '.', '#', '#', '#', '#', '#'
.byte '#', '#', '#', '#', '#', '.', '.', '#', '#', '#', '#', '#'
.byte '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'
.byte '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'
.byte '#', '#', '#', '#', '#', '.', '.', '#', '#', '#', '#', '#'
.byte '#', '#', '#', '#', '#', '.', '.', '#', '#', '#', '#', '#'
.text
# int main(void) {
# for (int row = 0; row < 6; row++) {
# for (int col = 0; col < 12; col++) {
# printf ("%c", flag[row][col]);
# }
# printf ("\n");
# }
# return 0;
# }
main:
# $t0 as `row`
# $t1 as `col`
out_loop_init:
li $t0, 0
out_loop_cond:
blt $t0, 6, out_loop_body
b out_loop_end
out_loop_body:
inner_loop_init:
li $t1, 0
inner_loop_cond:
blt $t1, 12, inner_loop_body
b inner_loop_end
inner_loop_body:
# printf ("%c", flag[row][col]);
# base + ((row * N_COL + col) * sizeof(char))
# flag + (($t0 * 12 + $t1) * 1)
mul $t2, $t0, 12 # row * N_COL
add $t2, $t2, $t1 # + col
mul $t2, $t2, 1 # * sizeof(char)
lw $t2, flag($t2) # flag + offset (BUG, should be LB)
li $v0, 11
move $a0, $t2
syscall
inner_loop_inc:
addi $t1, $t1, 1
b inner_loop_cond
inner_loop_end:
li $v0, 11
li $a0, '\n'
syscall
out_loop_inc:
addi $t0, $t0, 1
b out_loop_cond
out_loop_end:
# return 0;
li $v0, 0
jr $ra
error: your program tried to read uninitialised memory
the instruction that failed was:
0x00400058 50 [0x000a2021] addu $a0, $zero, $t2 # move $a0, $t2
this happened because $t2 was uninitialised
| the instruction that caused $t2 to become uninitialised was:
| 0x00400050 [0x2002000b] addi $v0, $zero, 11
Currently the error is missing one peace of important information the actual invalid address.
In this case: 0x10010045
The error would also be improved if it printed addition registers/labels involved in the error. In this case:
flag: 0x10010000
$at = 0x00000045
$t2 = 0x10010045
this should now be improved. feel free to review latest mipsy, and reopen with any specific improvement suggestions.
Printing more registers value can't be a bad thing.
Optimally (in my opinion) the registers values at both the time the uninitiated memory is used and the time the uninitiated memory is accessed would be better. And if the accesse occurs with one of the more advanced addressing modes each component is printed.
Eg. Give an error at:
ADD $t9, $s4, $t0
Caused by:
LW $t0, data+4($s0)
Would show the values of
$s4
, $t0
, data
, $s0
, and data+4($s0)
Additional questions. What happens with two uninitiated data access occurs simultaneously?
Give an error at:
ADD $t9, $t1, $t0
Caused by:
LW $t0, data+4($s0)
LW $t1, data+4($s1)
I think both errors should be printed together.
Adding backburner
as the error provides enough information to be useful as is.
Additionally there should be a better error message when the memory location is partially uninitiated.
Eg
When 0x10010000 is initialised 0x10010001 is initialised 0x10010002 is initialised 0x10010003 is uninitialised
LW $t0, 0x10010000
Will simply say that 0x10010000 is uninitiated, which isn't strictly speaking true.