c++ - GCC 为 AVR 上的简单 ISR 生成不必要的寄存器推送

标签 c++ avr

我有一些简单的 C++ 程序,如果使用 g++ 编译,它会生成以下汇编程序文本。唯一的语句是 sbi,它不影响任何状态标志。我想知道为什么 G++ 会产生这些无用的 r0r1 的 push/pop?

.global __vector_14
        .type   __vector_14, @function
__vector_14:
        push r1  ; 
        push r0  ; 
        in r0,__SREG__   ; ,
        push r0  ; 
        clr __zero_reg__         ; 
/* prologue: Signal */
/* frame size = 0 */
/* stack size = 3 */
.L__stack_usage = 3
        sbi 0x1e,0       ; ,
/* epilogue start */
        pop r0   ; 
        out __SREG__,r0  ; ,
        pop r0   ; 
        pop r1   ; 
        reti
        .size   __vector_14, .-__vector_14

有什么方法可以让 g++ 自动忽略这些寄存器保存。我一般不想将 ISR 声明为 ISR_NAKED

编辑: 这是相应的 C++ 代码(-Os 或 -O3):

#include <avr/interrupt.h>

struct AppFlags final {
    bool expired : 1;
} __attribute__((packed));

int main() {
}

ISR(TIMER0_COMPA_vect) {
    auto f = reinterpret_cast<volatile AppFlags*>(0x3e);
    f->expired = true;
}

最佳答案

简单的回答:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=20296

The difficulty is, that the present architecture of the avr back-end does not easily permit to improve this case: Every instruction pattern (like "multiply two 16 bit integers" or "sign-extend a 16 bit variable to 32 bits") presently is free to assume that may overwrite or change r0 and r1 unless it leaves the "zero_reg" with 0 after finishing it's task.

Resolving this issue, IMHO, would require a major refactoring of the back-end.

这是对 avr-backend 的一个长期存在的错误/增强请求。

关于c++ - GCC 为 AVR 上的简单 ISR 生成不必要的寄存器推送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44493718/

相关文章:

c - 嵌入式 C : Able to access some struct members but not others

c - 使用中断的 I2C 主发送器

arduino - avrdude.exe : invalid file format ' ' in update specifier error after setting up AVR studio 6 external tools

c++ - 在 emacs 中执行多个 gdb 命令

c++ - 一个类的方法作为另一个类的回调

c - 检测正弦波的频率/周期

c++ - 如何检查我的输入文件是否已更新?

c++ - 无法将 void* 动态转换为模板类

c# - 此 C++ 代码的 C# 等价物是什么(带有 InPtr)

c++ - 在没有动态分配的情况下在构造对象时避免数据的多个拷贝