I'm learning how to convert RISC-V assembly code to C, and I don't understand this conversion. A few questions I have:
- why is
t1being initialized to6instead of0? - We're using bne to compare t1 and t2, but we were taught to use the opposite, meaning the C code would be
while (t1 == t0). It appears this opposite technique was used forif (t1 ==0). Why? - Lastly, why is
addi t0, t0, -1used instead of sub?
Any insight is so greatly appreciated. My classroom environment is fast paced and not very question friendly, so I'm nervous to ask in lecture.
main:
# Tests simple looping behavior
li t0, 60
li t1, 0
loop:
addi t1, t1, 5
addi t0, t0, -1
bne t1, t0, loop
bne t1, zero, success
failure:
li a0, 0
li a7, 93
ecall
success:
li a0, 42
li a7, 93
ecall
This is the answer I was given:
int main(){
int t0 = 60;
int t1 = 6;
while(t1 != t0){
t1 = t1 + 5;
t0 = t0 - 1;
}
if(t1 == 0){
int a0 = 0;
return 0;
}else{
int a0 = 42;
return 0;
}
}
We were taught to use the opposite of bne/beq when converting C to RISC-V, so it's confusing why the 'correct' C conversion for this RISC-V assembly would include while (t1 != t0).
Initializing t1 to 6 also doesn't make any sense to me. It looks to be clearly loaded to 0 with 'li t1, 0'.
t1 = 0nott1 = 6. Perhaps a typo or OCR error if this material was printed out and scanned back in or something. Thoseecalls areexit(0)andexit(42), notreturnstatements. The rest looks right, though. Try it yourself, single-stepping through the asm vs. through the C program, watching registers or variables change, respectively. It should be clear that execution stays in the loop until they're equal, i.e. while they're not equal.do ... while ()whereas the C code is doingwhile () { /* do */ ...}. The difference is that the do/while will execute one iteration before checking the exit condition, whereas the while/do code will check the exit condition before the first iteration. So, here's another example of how these two (C vs. assembly) are not really identical.