【问题标题】:How the heck does this compile to 4kb?这到底是怎么编译成 4kb 的?
【发布时间】:2013-10-09 04:22:33
【问题描述】:
#define F_CPU 1000000

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

const uint8_t sequences[] = {
    0b00000001, 
    0b00000011,
    0b00000110,
    0b00001100,
    0b00011000,
    0b00110000,
    0b00100000,
    0b00110000,
    0b00011000,
    0b00001100,
    0b00000110,
    0b00000011,
    0b00000001,
};

const uint8_t totalSequences = sizeof(sequences) / sizeof(sequences[0]);

int main(void) {
    DDRB = 0b00111111;

    uint8_t i;
    uint8_t b;

    while(1) {
        for(i = 0; i < totalSequences; i++) {
            const uint8_t currentSequence = sequences[i];
            const uint8_t nextSequence = sequences[(i + 1) % totalSequences];

            // blend between sequences
            for(b = 0; b < 100; b++) {
                PORTB = currentSequence;  _delay_us(b);
                PORTB = nextSequence;     _delay_us(100-b);
            }

            _delay_ms(50);
        }
    }

    return 0;
}

这是我的整个程序。当我像下面这样直接设置 PORTB(没有混合)时,编译的二进制文件是 214 字节。当我包含第二个 for 循环时,我编译的二进制文件超过 4kb。我只有 1kb 的 FLASH 可用,所以我需要把它放在那里。

const uint8_t currentSequence = sequences[i];
const uint8_t nextSequence = sequences[(i + 1) % totalSequences];

//// blend between sequences
//for(b = 0; b < 100; b++) {
//  PORTB = currentSequence;  _delay_us(b);
//  PORTB = nextSequence;     _delay_us(100-b);
//}

PORTB = currentSequence;
PORTB = nextSequence;
_delay_ms(50);

我的工具链是WINAVR,编译如下:

avr-gcc -Os -mmcu=attiny13 -Wall -std=c99 main.c -o main.out
avr-objcopy -O binary main.out main.bin

我没有足够的知识来反编译二进制文件并查看编译器做了什么,但不管它是什么,它都是错误的。为什么带有内循环的二进制文件是 4kb,我该如何修复它?

修改后的循环(278 字节):

while(1) {
    for(i = 0; i < totalSequences; i++) {
        const uint8_t currentSequence = sequences[i];
        const uint8_t nextSequence = sequences[(i + 1) % totalSequences];

        // blend between sequences
        for(b = 0; b < 100; b++) {
            int d;
            PORTB = currentSequence;  for(d = 0; d < b; d++,   _delay_us(1));
            PORTB = nextSequence;     for(d = 100; b < d; d--, _delay_us(1));
        }

        _delay_ms(50);
    }
}

【问题讨论】:

  • 我建议查看地图文件。您应该能够通过添加 -Wl,-Map=output.map 让 GCC 生成地图文件

标签: c optimization avr avr-gcc


【解决方案1】:

delay() 函数会放大代码大小,除非参数是编译时间常数。它也不会通过可变参数延迟正确的时间。

【讨论】:

  • 请检查我在 OP 中修改后的循环。编译后的二进制文件现在是 278 字节。那一个会更好吗?
猜你喜欢
  • 2019-12-19
  • 2011-12-05
  • 2017-05-20
  • 2019-01-24
  • 1970-01-01
  • 1970-01-01
  • 2020-03-06
  • 2011-05-26
  • 2011-09-03
相关资源
最近更新 更多