abeta201
abeta201

Reputation: 243

Returning More Than 1 Byte to a Function in Assembly

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

Answers (1)

Martin Rosenau
Martin Rosenau

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

Related Questions