gpt4 book ai didi

c - AVR-GCC破坏性优化

转载 作者:行者123 更新时间:2023-12-02 06:18:11 25 4
gpt4 key购买 nike

我正在使用avr-gcc 4.8.2对Atmel ATtiny13a微 Controller 进行编程。

这是我的C代码:

#include <avr/io.h> 
#include <util/delay.h>

int main(void) {
DDRB = 1; // PB0 is output
for (uint8_t i = 0; i < 10; i++) {
PORTB = 1;
_delay_ms(500);
PORTB = 0;
_delay_ms(500);
}
while(1);
}

void test(void) {
DDRB = 1; // PB0 is output
for (uint8_t i = 0; i < 10; i++) {
PORTB = 1;
_delay_ms(100);
PORTB = 0;
_delay_ms(100);
}
}

永远不会从主功能调用测试功能(LED的快速闪烁),因此 Controller 应仅进入主功能(缓慢闪烁)。

当我用 -O1编译代码时,一切正常:
avr-gcc -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -mmcu=attiny13 -DF_CPU=1200000   -Wall -Wstrict-prototypes -Os -c test.c -o test.o
avr-gcc test.o -o test.elf
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature test.elf test.hex

但是,如果我使用 -Os(大小优化)或 -O2,则微 Controller 将运行 test函数而不是 main函数:LED快速闪烁且永不停止。
-Os标志使用起来是否太危险了,应该避免吗?还是我可以在代码中进行某些更改以避免这种错误? ATtiny13a仅具有1K的闪存,因此减小尺寸非常重要。

编辑:如注释中所建议,这是带有 -O1-O2的汇编程序差异: http://www.diffchecker.com/3l9cdln6

在其中,您可以看到 -O2将第一部分从 .text更改为 .text.startup
--- test.o1.txt 2013-12-03 19:10:43.874598682 +0100
+++ test.o2.txt 2013-12-03 19:10:50.574674155 +0100
@@ -3,7 +3,7 @@
__SREG__ = 0x3f
__tmp_reg__ = 0
__zero_reg__ = 1
- .text
+ .section .text.startup,"ax",@progbits
.global main
.type main, @function
main:

这可能是这里的主要问题。经过进一步测试后,我发现罪魁祸首是 -freorder-functions优化。有没有办法防止这种行为?

最佳答案

我进行了一些进一步的调试,发现“罪魁祸首”是-freorder-functions优化。它在手册页中记录如下:

-freorder-functions
Reorder functions in the object file in order to improve code locality.
This is implemented by using special subsections ".text.hot" for most
frequently executed functions and ".text.unlikely" for unlikely executed
functions. Reordering is done by the linker so object file format must
support named sections and linker must place them in a reasonable way.

文档中的最后一行解释了我遇到的/造成的问题。如果我们再次查看原始问题中的编译命令:
$ avr-gcc -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct \
-fshort-enums -mmcu=attiny13 -DF_CPU=1200000 -Wall -Wstrict-prototypes \
-Os -c test.c -o test.o
$ avr-gcc test.o -o test.elf

...我们看到我正在将优化标志传递给编译器,但没有传递给链接器。我以为 CFLAGS仅影响编译而不影响链接,因此我没有将它们传递给链接器,但是在那种情况下我错了。

结果:编译器对汇编代码进行了重新排序(包括适当的标签),但是链接程序未考虑这些标签。而且由于 test函数由编译器放置在 main函数之前,而不是由链接器重新安排,因此,这是在微 Controller 上实际执行的代码。

因此,解决方案变成了: 编译器标志也应该传递给链接器!

关于c - AVR-GCC破坏性优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20356871/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com