代码:
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
现在,正如我所看到的,至少有一个,最多两个推 - 弹对可以被淘汰:
保存一个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
...
看到没有代码使用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
...
其中任何一个都可以节省宝贵的字节和微秒。
有没有办法可以将这些或类似的优化放入atmel工作室工具链/库中,以便我的编译代码生成得更好?
围绕中断和函数调用的许多代码,以及一些C到汇编语言的翻译都可以进行很多优化。
答案 0 :(得分:1)
我还发现可以优化生成的汇编代码。那个时候我没有使用-On
选项。
我发现了一个被调用函数的代码(它在寄存器中取一个参数);将它复制到堆栈(保持一个干净的副本作为'自动'C变量...在大多数情况下是无用的)和FURTHERMORE将这个值复制回原始寄存器!虽然之前刚刚阅读过该注册表,但GCC应该知道它。
如果您使用Atmel Studio和默认编译器(GCC),您的二进制代码优化取决于工具链行为(因此,在其命令行中指定选项)。
要获得最佳结果,您可以尝试直接使用avr-gcc编译源树(以设置Atmel Studio无法为您设置的选项)。
使用另一种工具链是另一种获得(理论上)最佳结果的方法。 无论如何,我怀疑任何其他工具链会给出(整体)比GCC更好的结果。