AtmelStudio编译代码:如何优化编译器

时间:2015-11-12 19:45:50

标签: c assembly compiler-construction atmega atmelstudio

代码:

uint8_t count;

ISR(TIMER1_OVF_vect, ISR_NAKED)
{
    count++;
    reti();
}

生成的程序集是:

--- F:\atmel-prj\compiler-test2\compiler-test2\Debug/.././compiler-test2.c -----
{
00000048  PUSH R1       Push register on stack 
00000049  PUSH R0       Push register on stack 
0000004A  IN R0,0x3F        In from I/O location 
0000004B  PUSH R0       Push register on stack 
0000004C  CLR R1        Clear Register 
0000004D  PUSH R24      Push register on stack 
    count++;
0000004E  LDS R24,0x0100        Load direct from data space 
00000050  SUBI R24,0xFF     Subtract immediate 
00000051  STS 0x0100,R24        Store direct to data space 
}
00000053  POP R24       Pop register from stack 
00000054  POP R0        Pop register from stack 
00000055  OUT 0x3F,R0       Out to I/O location 
00000056  POP R0        Pop register from stack 
00000057  POP R1        Pop register from stack 
00000058  RETI      Interrupt return 

现在,正如我所看到的,至少有一个,最多两个推 - 弹对可以被淘汰:

  1. 保存一个push-pop,使用r0取消r24

    PUSH R1     Push register on stack 
    PUSH R0     Push register on stack 
    IN R0,0x3F      In from I/O location 
    PUSH R0     Push register on stack 
    CLR R1      Clear Register 
    count++;
    LDS R0,0x0100       Load direct from data space 
    SUBI R0,0xFF        Subtract immediate 
    STS 0x0100,R0       Store direct to data space 
    ...
    
  2. 看到没有代码使用r1作为0值,所以只使用r1用于所有目的。

    PUSH R1     Push register on stack 
    IN R1,0x3F      In from I/O location 
    PUSH R1     Push register on stack 
    CLR R1      Clear Register 
    count++;
    LDS R0,0x0100       Load direct from data space 
    SUBI R0,0xFF        Subtract immediate 
    STS 0x0100,R0       Store direct to data space 
    ...
    
  3. 其中任何一个都可以节省宝贵的字节和微秒。

    有没有办法可以将这些或类似的优化放入atmel工作室工具链/库中,以便我的编译代码生成得更好?
    围绕中断和函数调用的许多代码,以及一些C到汇编语言的翻译都可以进行很多优化。

1 个答案:

答案 0 :(得分:1)

我还发现可以优化生成的汇编代码。那个时候我没有使用-On选项。 我发现了一个被调用函数的代码(它在寄存器中取一个参数);将它复制到堆栈(保持一个干净的副本作为'自动'C变量...在大多数情况下是无用的)和FURTHERMORE将这个值复制回原始寄存器!虽然之前刚刚阅读过该注册表,但GCC应该知道它。

如果您使用Atmel Studio和默认编译器(GCC),您的二进制代码优化取决于工具链行为(因此,在其命令行中指定选项)。

要获得最佳结果,您可以尝试直接使用avr-gcc编译源树(以设置Atmel Studio无法为您设置的选项)。

使用另一种工具链是另一种获得(理论上)最佳结果的方法。 无论如何,我怀疑任何其他工具链会给出(整体)比GCC更好的结果。