MSP430 Comportamiento de puntero de pila y puntero de marco

1

Al intentar analizar un archivo de ensamblaje simple generado a través de msp430-gcc, me topé con un conjunto de instrucciones que no entiendo sobre el puntero del marco y el puntero de la pila del MSP430.

Programa C:

#include "msp430g2553.h"

int main()
{
  int i;

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

}

Directivas de ensamblaje menos:

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

Intenté comentar el código para rastrear la ejecución del programa, pero no entiendo la línea add #2, r4 . ¿Qué sucede exactamente aquí y por qué se hace referencia a int i en -4(r4) ?

    
pregunta Alan W

2 respuestas

2

Parece que el compilador ha asignado espacio para la variable local en la pila, en lugar de usar un registro de reserva.

Preguntaste específicamente sobre estas líneas:

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

Vemos un desmontaje inusual de -4(r4) como destino para dos instrucciones. Esto se llama registrar el direccionamiento indexado y puede leer más sobre esto en manual msp-gcc :

  

MSP430 modos de direccionamiento

     

Indexado. El operando está en la memoria en la dirección Rn+x

Por lo tanto, el destino de estas instrucciones se encuentra a 4 bytes antes de la dirección almacenada en r4 . Es un poco como el equivalente en C: *(pointer - 4) .

Aunque es un programa simple que le gustaría compilar con diferentes niveles de optimización. Debería ver a GCC comenzar a hacer cosas interesantes, como omitir el prólogo de la función donde no es necesario y quizás usar un registro para la variable i .

    
respondido por el David
2
                 |                |
                 |----------------|
                 |                |
       B ===>    |----------------|   ||
                 | return address |   ||
       A ===>    |----------------|   ||  Stack
                 |       i        |   ||  grows
       C ===>    |----------------|   ||  downward
                 |                |   ||
                 |----------------|   \/
                 |                |
                 |----------------|
                 |                |

Cuando main comienza a ejecutarse, el puntero de la pila de hardware, r1 , apunta a la dirección "A", donde reside la dirección de retorno de la función que llamó main .

r4 se está utilizando como puntero de marco de pila, y por cualquier razón, los diseñadores de software optaron por tener este punto para abordar "B", que era la parte superior de la pila antes del dirección de retorno fue empujado Esto significa que las compensaciones positivas accederán a los datos, etc., que pertenecen a la persona que llama, y las compensaciones negativas accederán a los datos locales a main , incluida la dirección de retorno. Es probable que si main devolviera un valor, se almacenaría en la dirección "B" (compensación de 0 desde r4 ), donde sería la última cosa en la pila después de que devuelva main .

main tiene una variable local, i , que se asigna en la pila. En lugar de presionar un valor inicial para i , el software simplemente reduce el puntero de pila en 2 para crear el espacio para él en la dirección "C". Ahora, si main llama a otras funciones, la dirección de retorno se almacenará justo debajo de i en la pila. Sin embargo, el desplazamiento de "B" a "C" es -4, por lo que el código usa ese valor cada vez que necesita acceder a i .

Es un poco extraño que r4 en sí no haya sido insertado en la pila antes de escribirse (guardando así el puntero del cuadro de pila anterior), pero quizás esto sea algo que realiza el llamador en este sistema.

    
respondido por el Dave Tweed

Lea otras preguntas en las etiquetas