Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Five Tips to Writing RISC-V Assembly (stephenmarz.com)
73 points by azhenley on May 23, 2021 | hide | past | favorite | 5 comments



Understandable the architecture calling conventions are important - if registers are marked as destroyed you must treat them as such, even if in your code it seems they’re preserved.

Single-stepping debuggers have caused weird side effects in the past (the trap instruction coincidentally keeps a register with a “sane” value and so it’s not noticed that in normal operation it gets scrambled).


Note that the base RISC-V ISA (IMA extensions) doesn't say anything about calling conventions or functions (calls and returns) or even a stack. All X registers except X0 are interchangeable.

Which registers are caller save or callee save or even which is the stack pointer or function return address is all purely a software convention in a particular OS and/or compiler.

(the C extension gives greater program compression if used with an ABI that uses X1 as the Return Address and X2 as the Stack Pointer, and X8-X15 as the most commonly used registers, but even then nothing breaks if you don't)


This is imprecise wrt the point of view of caller vs callee.

> All a (argument) and t (temporary) registers must be considered destroyed after a function call. All s (saved) registers can be considered saved after a function call.

Who must do the considering here? The caller or the callee? I expect it's the caller because that makes the most sense, but I'd like to see it spelled out.

If my assumption is correct, that implies that callees are required to restore the s registers before returning but they are not required to restore a or t registers before returning. Correct?


A and T are "caller saved", meaning that if I want their value after I make a function call, I, the caller, must save the registers. So,

li t0, 10 call somefunc # Must consider t0 destroyed here unless we save it first

The saved registers are different li s0, 10 call somefunc # Can consider s0 = 10 here.

However, if we use the s registers, we have to make sure we put it back the way we found it. So, before li s0, 10, I need to save the old value of s0.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: