Reputation: 243
I'm new to assembly (I'm using an Arduino Uno with AVR assembly) and I can't figure out how to return variables of more than 1 byte from an assembly function. So far, I have only needed to return bytes, and I have simply modified the r24 register with mov
and ldi
to the value I wanted to return. When I call ret
, the function returns the value in register r24 to a program in C. But how do I return values larger than 8 bytes? Basically, how do I use memory instead of the registers.
Upvotes: 1
Views: 966
Reputation: 18503
On the page you have linked in your comment (gcc.gnu.org/wiki/avr-gcc) read the chapter "Calling Convention". Unfortunately it's a bit more complicated than for other CPUs.
If the value returned is longer than 8 bytes the C compiler will allocate the memory and pass the address of the memory in registers R25:R24.
All arguments are shifted "down" by two registers. Example:
byte someFunction1(byte a, byte b);
a -> R24
b -> R22
return -> R24
struct largeStructure someFunction2(byte a, byte b);
a -> R22 (instead of R24)
b -> R20 (instead of R22)
address of tmp_mem -> R25:R24
return -> in memory tmp_mem
If the value returned is up to 8 bytes long the value is returned in the following registers:
1 byte: R24
2 bytes: R24...R25
3 bytes: R22...R24
4 bytes: R22...R25
5 bytes: R20...R24
6 bytes: R20...R25
7 bytes: R18...R24
8 bytes: R18...R25
Upvotes: 2