Initializing the stack

Stack initialization is performed in the prologue of "main()". This suits most cases. However, you redefine startup, and needs some space allocated on the stack, the stack has to be explicitly initialized. For example:

#define STACKINITIALVALUE	0x0280

NAKED(_reset_vector__)
{
    /* Initialise the stack */
    __asm__ __volatile__("mov %0, r1"::"i" (STACKINITIALVALUE));

    /* Your startup code goes here */

    __asm__ __volatile__("br #main"::);
}
*** NOTE *** DO NOT USE the register definitions PC, SP and SR, which some other MSP430 tools (e.g. IAR) recognise. The as assembler in binutils does not recognise these names. Instead use r0, r1 and r2.

The stack finally will be initialized in main(). Normally, the initial stack pointer address is at top of RAM. If you want to reserve some RAM space, which is not accessible by the compiler, you may specify -mno-stack-init flag and then define startup as follows:

#define STACKINITIALVALUE	0x0280

NAKED(_reset_vector__)
{
    char a[100];	/* Will be allocated on the stack */

    __asm__ __volatile__("mov       #__data_start ,r1"::);

    /* Your startup code goes here */

    /* Initialise the stack */
    __asm__ __volatile__("mov %0, r1"::"i" (STACKINITIALVALUE));
    /* Jump to main */
    __asm__ __volatile__("br #main"::);
}
If you do not make the function declaration NAKED, note that on function exit, the frame pointer value will be added to r1. Therefore, the stack initialisation should be as follows:
...
__asm__ __volatile__("mov %0, r1" :: "i" (STACKINITIALVLUE) );
__asm__ __volatile__("sub #.L__FrameSize__reset_vector__, r1"::);
...
*** NOTE *** The frame pointer register (r4) and arguments pointer register (r5) values are compiled in a mysterious way. Use them with care.

The variable ".L__FrameSize_[function name]" is defined by the compiler, and has a value of the stack space required by the function. For example:

#define STACKINITIALVALUE 0x280

void set(char *a) {}	// dummy
void reset(char *a) {}  // dummy

void _reset_vector__()
{
    __asm__ __volatile__("mov       #__data_start ,r1"::);
    {
        char a[100];
        set(a);
        reset(a);
    }
    __asm__ __volatile__("mov %0, r1"::"i" (STACKINITIALVALUE));
    __asm__ __volatile__("sub #.L__FrameSize__reset_vector__, r1"::);
    __asm__ __volatile__("br #main"::);
}

int main()
{
    ...
}
compiled with
$ msp430-gcc -O m.c -mendup-at=main -mno-stack-init
will result in:

---
a.out:     file format elf32-msp430

Disassembly of section .text:

0000fc00 <__zero_vector>:
    fc00:       30 40 04 fc     br      #0xfc04

0000fc04 <_unexpected_>:
    fc04:       00 13           reti

0000fc06 <set>:
    fc06:       30 41           ret

0000fc08 <reset>:
    fc08:       30 41           ret

0000fc0a <_reset_vector__>:
    fc0a:       31 80 64 00     sub     #100,   SP      ;  #0x0064
    fc0e:       31 40 00 02     mov     #512,   SP      ;  #0x0200
    fc12:       0f 41           mov     r1,     r15
    fc14:       b0 12 06 fc     call    #-1018          ;  #0xfc06
    fc18:       0f 41           mov     r1,     r15
    fc1a:       b0 12 08 fc     call    #-1016          ;  #0xfc08
    fc1e:       31 40 80 02     mov     #640,   SP      ;  #0x0280
    fc22:       30 40 30 fc     br      #0xfc30
    fc26:       31 80 64 00     sub     #100,   SP      ;  #0x0064
    fc2a:       31 50 64 00     add     #100,   SP      ;  #0x0064
    fc2e:       30 41           ret

0000fc30 <main>:
    fc30:       30 40 30 fc     br      #0xfc30
....
---

In this case, the "RESERVE_RAM" attribute to the "main()" function would be a simpler way to achieve the same effect.