我正在使用AVR-GCC 4.9.2,我想知道在AVR上的ISR中如果发生早期返回会发生什么?
ISR(USART_RXC_vect)
{
...
if(idx == BUFSIZE)
return;
...
}
在汇编中,return
会被翻译成ret
指令吗?还是我需要自己加上reti()
指令?
我想要了解背后发生的详细情况。
ISR(USART_RXC_vect)
USART_INTERUPT_VECTOR:
return;
不是字面意义上的
ret
或者
reti
在汇编中。
在C/C++中,这两个指令将被翻译成多个汇编语句,而且在两种情况下,它们的解释都取决于上下文。在这种情况下,ISR(){}
的上下文相当单一,但它很可能也包括一些推送和存储SREG。但是堆栈中推送的数量将取决于函数中发生的事情。
因此,任何return;
都将在上下文中进行解释。在实际构建为子程序的普通子例程的结尾处(出于代码效率原因,许多有限用途的子例程会被编译器“内联”),它将变成一个ret
指令(在处理任何所需的POP和其他低级清理之后)。在中断结束时,它实际上将意味着“弹出您之前推送的所有内容(并还原SREG),然后reti
”。
当您返回将被编译成通过平台系统传输该值的类型时,需要在包括ret
指令之前进行。因此,return;
是一个非常上下文敏感的语句,您可以假设它会被正确解释,除非您做了非常奇怪的事情。但这些奇怪的事情至少会被像AVR-GCC这样的好编译器警告。