On Fri, Jan 03, 2014 at 04:12:19PM +0800, Bin.Cheng wrote:
> Hi, For below simple example:
> #include <stdint.h>
>
> extern uint32_t __bss_start[];
> extern uint32_t __data_start[];
>
> void Reset_Handler(void)
> {
> /* Clear .bss section (initialize with zeros) */
> for (uint32_t* bss_ptr = __bss_start; bss_ptr != __data_start; ++bss_ptr) {
> *bss_ptr = 0;
> }
> }
I believe this is undefined behavior, so GCC can assume
bss_ptr != __data_start is true always. You need something like
memset (__bss_start, 0, (uintptr_t) __data_start - (uintptr_t) __bss_start);
(note the cases to non-pointers), then it is just implementation defined
behavior. Or do
uint32_t data_ptr;
asm ("" : "g" (data_ptr) : "0" (__data_start));
for (uint32_t* bss_ptr = __bss_start; bss_ptr != data_ptr; ++bss_ptr) {
*bss_ptr = 0;
}
and thus hide from the compiler the fact that __data_start is in a different
object.
Jakub