I have mixed C code with assembler to understand task switching on AVR. This is only for my personal academic use and I know there is freeRTOS but I want to understand. At the moment I'm struggling on how the return address is stored on the stack.
Assume there are three functions:
extern void call(void(*)() fn);
void f1() {
// Do something
while(1){};
}
void f2() {
// Do something
while(1){};
}
int main() {
caller(&f1);
while(1){};
}
The Assembler file looks like this:
.section .text
.global caller
caller:
// Register r25 and r24 contain the pointer
pop r0
pop r0
push r25
push r24
ret
The AVR instruction set documentation states that two bytes (for PC with 16bit) are pushed on the stack when a call instruction is executed. When using avr-gcc in combination with assembler, this does not work as expected. As I understand the return address on the stack this assembler code should return to the address of f2 but this doesn't happen.
Is there anything I forgot about how gcc passes function pointers? I know this is no real world code but the intention is to help me understand about the return behaviour. The listing for calling the caller function tells me that r25 and r24 are loaded with some address.
while(1){}
). – jwdonahuemain()
. Step into the code with a debugger and look at the actual instruction pointer values before and after the call tocaller
. – jwdonahue