Global Array Size Affects Clock Frequency Only On Linux (avr-gcc)

I am having the most peculiar problem. When the size of a global array changes, it alters the clock frequency of the ATmega164a. This is on Linux. When compiled on Windows, this problem doesn't occur (irrespective of whether the .hex file is actually programmed onto the ATmega164a in Windows or Linux aka I don't suspect avrdude is contributing to this problem). I even ran on Linux the exact commands run by AVR Studio to build the target, and still encountered this problem.

The CLKDIV8 fuse is not set, and the Internal RC fuse is set, so the ATmega164a should be running at 8MHz nominal.

This is the minimum working example of the code that runs correctly:

#include <avr/io.h>
uint8_t bytes[6];
int main(void){
DDRB = (1<<PB5);

while(1){
PORTB |= (1<<PB5);
PORTB &= ~(1<<PB5);
}
}


An oscilloscope shows the resulting pulse is 250ns wide (2 cycles).

However, increasing the global array size by one results in odd behavioral.

#include <avr/io.h>
uint8_t bytes[7];
int main(void){
DDRB = (1<<PB5);

while(1){
PORTB |= (1<<PB5);
PORTB &= ~(1<<PB5);
}
}


An oscilloscope shows this pulse width as 444ns, and the time between pulses increases in the same ratio which indicates the clock frequency has decreased.

I have no clue where to go from here. It took me a very long time just to narrow it down to this minimum working example. I have pasted my Makefile to pastebin.

EDIT

Here are the listing files for the two cases. bytes[6]: pastebin bytes[7]: pastebin

I have verified with a 16bit timer that the clock frequency is indeed decreasing by the factor previously quoted (250ns -> 444ns).

• Post the assembly listing for both cases. – apalopohapa Feb 23 '13 at 11:19
• This isn't a particularly reliable way of measuring clock frequency. Maybe use a timer with Max. Prescaler and set it to toggle at top or what have you and measure that. You're then not affected by compiler quirks. – Chintalagiri Shashank Feb 23 '13 at 13:15
• @ThePhoton points out the Assembler listing only substantively has 1 line difference. 0x66 -> 0x67 @ adress 0x92. That means that the output (i.e. the hex code) that goes to the programmer should be compared. THe object/assembly code shows no evidence of difference. – placeholder Feb 23 '13 at 20:50