int a; /* .bss — 초기값 없음 */
int b = 5; /* .data — 초기값 있음 */
int c = 0; /* .bss — 0 은 초기값 없는 것과 같게 취급된다 */
바이너리에 실체가 없다
.bss 는 크기 정보만 들어 있다. 0 을 수천 개 저장할 이유가 없기 때문이다.
그래서 큰 배열을 0 으로 초기화해도 플래시 용량은 늘지 않는다.
uint8_t big[8192]; /* 플래시 0바이트, RAM 8KB */
uint8_t big2[8192] = {1}; /* .data — 플래시도 8KB 먹는다 */
두 번째 형태를 무심코 쓰면 플래시가 갑자기 부족해진다.
0 으로 채워지는 시점
Reset_Handler 가 main 전에 채운다. 그래서 초기화 안 한 전역은 0 이라는 C 규칙이 지켜진다.
이 루틴이 잘못되면 전역이 쓰레기 값으로 시작하고, 증상이 엉뚱한 곳에서 나타난다.
알아 둘 것
지역 변수는 여기 없다 — 스택에 잡히고 자동으로 0 이 되지 않는다. 그리고 스택이 넘치면 바로 이 영역을 덮어쓴다.