Electronic – MSP430 Stack pointer and frame pointer behavior

assemblycmsp430

While trying to analyze a simple Assembly file generated through the msp430-gcc, I stumbled upon a set of instructions that I don't understand dealing with the frame pointer and the MSP430's stack pointer.

C Program:

#include "msp430g2553.h"

int main()
{
  int i;

  for(i = 0; i < 3; i++);

}

Assembly minus directives:

main:
        mov     r1, r4 ;Stores address of stack pointer in r4(frame pointer)
        add     #2, r4 ; ?
        sub     #2, r1 ; subtract 2 to allocate int i
        mov     #0, -4(r4) ; assign 0 to i
        jmp     .L2 ; start loop
.L3:
        add     #1, -4(r4) ; Adds one to int i
.L2:
        cmp     #3, -4(r4) ; Compare to #3
        jl      .L3 ; jump to .L3 if true
        add     #2, r1 ; deallocate int i
.Lfe1:
        .size   main,.Lfe1-main

I tried commenting the code to trace the program's execution, but I don't understand the line add #2, r4. What exactly is happening here, and why is int i being referenced at -4(r4)?

Best Answer

It looks like the compiler has allocated space for the local variable on the stack, rather than using a spare register.

You asked specifically about these lines:

    mov     #0, -4(r4) ; assign 0 to i
    add     #1, -4(r4) ; Adds one to int i

We see an unusual disassembly of -4(r4) as the destination for two instructions. This is called register indexed addressing and you can read more about it in the msp-gcc manual:

MSP430 addressing modes

Indexed. The operand is in memory at address Rn+x

Therefore the destination for these instructions is located 4 bytes before the address stored in r4. It's a bit like the equivalent in C: *(pointer - 4).

Although it is a simple program you might like to recompile with varying levels of optimisation. You should see GCC start to do interesting things like omitting the function prologue where it isn't required and perhaps using a register for the i variable.