GCC 中的汇编代码未在 Atmel Studio 中针对 AVR 环境进行编译

Assembly code in GCC is not being compiled in Atmel Studio for AVR environment

我正在尝试删除程序中的中断向量 table 以减少闪存的使用。

我已经成功使用了 -nostartfiles 标志,它在输出中删除了很多汇编代码。

要使用该程序,我必须设置堆栈指针。我找到了这样做的代码:

asm volatile ( ".set __stack, %0" :: "i" (RAMEND) );

但是在编译时,它什么都不做,而其他汇编代码如

asm volatile ( "clr __zero_reg__" );      
asm volatile ( "rjmp main");

有效。

这是我当前的 C 代码:

void __init(void) __attribute__ ((naked)) __attribute__ ((section (".init9")));
void __init(void)
{
    asm volatile(".set __stack, %0" :: "i" (RAMEND) );
    asm volatile ( "clr __zero_reg__" );      
    asm volatile ( "rjmp main");             
}

编译为汇编(7892 和 7894 行):

void __jMain(void) __attribute__ ((naked)) __attribute__ ((section (".init9")));
void __jMain(void)
{
    asm volatile(".set __stack, %0" :: "i" (RAMEND) );
    asm volatile ( "clr __zero_reg__" );        
    7892:   11 24           eor r1, r1
    asm volatile ( "rjmp main");                
    7894:   02 c0           rjmp    .+4         ; 0x789a <main>
}

为什么 .set __stack 没有编译?我是否缺少一些编译器标志?尝试了很多东西.. 还检查了使用相同代码的引导加载程序,它们正在做同样的事情,但不知何故,我的编译不正确。

怎么样:

asm volatile(
        "ldi  r28, lo8(RAMEND)" "\n\t"
        "ldi  r29, hi8(RAMEND)" "\n\t"
        "out __SP_L__, r28" "\n\t"
        "out __SP_H__, r29" "\n\t"
 );

主要来源: https://ucexperiment.wordpress.com/2015/01/02/arduino-stack-painting/

我发现正确的"c"方法是:

void __init(void) __attribute__ ((naked)) __attribute__ ((section (".init9")));
void __init(void)
{   
    asm volatile ("clr __zero_reg__");
    SP = RAMEND;   
    asm volatile ( "rjmp main");             
}

在最后,它跳转到您的主要功能。这会产生 yumbrad 提出的以下汇编输出:

// asm volatile ("clr __zero_reg__");
7800:   11 24           eor r1, r1

// SP = RAMEND;   
7802:   8f ef           ldi r24, 0xFF   ; 255
7804:   98 e0           ldi r25, 0x08   ; 8
7806:   9e bf           out 0x3e, r25   ; 62
7808:   8d bf           out 0x3d, r24   ; 61

// asm volatile ( "rjmp main");             
780a:   00 c0           rjmp    .+0         ; 0x780c <main>