Bare-metal start-up code for Cortex M3 .bss region initialization
As you suspect, this is happening because the unsigned int data type is 4 bytes in size. Each *bss_start_p = 0; statement actually clears four bytes of the bss area.

The bss memory range needs to be aligned correctly. You could simply define _BSS_START and _BSS_END so that the total size is a multiple of four, but this is usually handled by allowing the linker script to define the start and stop locations.

As an example, here is the linker section in one of my projects:

.bss (NOLOAD) : ALIGN(4)
{
    __bss_start__ = .;
    *(.bss)
    . = ALIGN(4);
    __bss_end__ = .;
} &gt;RAM


The ALIGN(4) statements take care of things.

Also, you may wish to change

while(bss_start_p != bss_end_p)

to

while(bss_start_p &lt; bss_end_p).

This won't prevent the problem (since you might be clearing 1-3 more bytes than you wish), but it could minimize the impact :)