The why:
This quotation is from linuxquestions.org. I did not use that option. Do
The global variable under discussion is declared in usbdrv.c:
This variable is used, but not declared, in usbdrvasm.S. But gcc (or avr-gcc, it's the same) considers all undeclared variables in an assembler source as externals. So, in usbdrv.s, it looks like this:
Now, if common variables are taken as globals by gcc, we have that usbDeviceId debuts as zero in the executable! The code to clear the .bss section CANNOT be seen in the assembler sources generated by gcc. It lies in some library and put ahead of the programmer's code by the linker. What do you know?
For a program running from the ROM of a microcontroller there likely is no loader, and the task of zeroing BSS would fall to the program's runtime startup routine (crt0 in the old days). According to the avr-libc manual, you have the option of placing uninitialized variables in the .bss section (which should be all zero) or the .noinit section, which is a .bss subset that does not get zeroed on startup.
This quotation is from linuxquestions.org. I did not use that option. Do
- avr-gcc -I. -c -S -mmcu=<avr device> usbdrv.c
.global __do_copy_data
.global __do_clear_bss
The global variable under discussion is declared in usbdrv.c:
- volatile char usbDeviceId;
This variable is used, but not declared, in usbdrvasm.S. But gcc (or avr-gcc, it's the same) considers all undeclared variables in an assembler source as externals. So, in usbdrv.s, it looks like this:
- .comm usbDeviceId,1,1
Now, if common variables are taken as globals by gcc, we have that usbDeviceId debuts as zero in the executable! The code to clear the .bss section CANNOT be seen in the assembler sources generated by gcc. It lies in some library and put ahead of the programmer's code by the linker. What do you know?