修改avr上函数的返回地址

时间:2018-03-16 21:52:35

标签: c assembly avr avr-gcc microprocessors

我将C代码与汇编程序混合在一起,以了解AVR上的任务切换。这仅供我个人学术使用,我知道有freeRTOS,但我想了解。目前,我正在努力研究返回地址如何存储在堆栈中。

假设有三个功能:

extern void call(void(*)() fn);

void f1() {
 // Do something
 while(1){};
}

void f2() {
 // Do something
 while(1){};
}

int main() {
 caller(&f1);
 while(1){};
}

汇编程序文件如下所示:

.section .text

.global caller
caller:
  // Register r25 and r24 contain the pointer
  pop r0
  pop r0
  push r25
  push r24
  ret

AVR指令集文档指出,当执行调用指令时,两个字节(对于具有16位的PC)被压入堆栈。将avr-gcc与汇编程序结合使用时,这不会按预期工作。据我理解堆栈上的返回地址,这个汇编代码应该返回到f2的地址,但这并没有发生。

我有没有忘记gcc如何通过函数指针?我知道这不是真正的世界代码,但目的是帮助我理解返回行为。调用调用函数的列表告诉我r25和r24加载了一些地址。

1 个答案:

答案 0 :(得分:0)

我是否忘记了gcc如何传递函数指针?

不。关于您如何推销价值:

push r25
push r24
ret

您必须先按地址(R24)的 low 部分。 cf.例如,在无法获得Z寄存器的情况下,avr-gcc如何实现indirect jump