关于守则:
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 现在,在我看来,至少有一个,最多两个推-弹出对可以被淘汰:
这两种方法都为我们节省了宝贵的字节和微秒。
有什么方法可以将这些或类似的优化放到atmel studio工具链/库中,这样我的编译代码的生成就会稍微好一些吗?
大量关于中断和函数调用的代码,以及一些C到汇编的转换可以进行大量的优化。
发布于 2016-01-14 21:31:03
我还发现生成的程序集代码可以进行优化。那时我还没有使用-On选项。我发现被调用函数的代码(它在寄存器中接受一个参数);将它复制到堆栈中(为了保持一个干净的副本作为一个‘自动’C变量.这在大多数情况下是无用的),并进一步将此值复制回原始寄存器!而这个登记册是以前读过的,GCC应该知道。
如果将Atmel Studio与默认编译器(即GCC )一起使用,则二进制代码优化取决于工具链行为(因此也取决于其命令行中指定的选项)。
要获得最好的结果,您可以使用avr直接编译源代码树(设置Atmel Studio无法为您设置的选项)。
使用另一个工具链是获得(理论上的)最好结果的另一种方法。无论如何,我怀疑任何其他的工具链都不会比GCC提供更好的结果。
https://stackoverflow.com/questions/33680011
复制相似问题