¿Cómo se asigna la matriz en la pila?

2

Estaba probando el siguiente código en mi placa STM32, pero no podía entender cómo se asignaba la matriz en la pila.

Supongo que hay 200 bytes de memoria en STM32.

Aquí está el código:

void test1()
{
  char data[1000]={0};
}

void test2()
{
  char data[1000];
  data[999] = 50;
  lcdAdjustBacklight(data[999]);//just adjust back light
}

Entonces, cuando agrego test1() en mi función main() , el programa se bloqueará cuando se ejecute en la MCU. Obviamente, la pila está desbordada. Sin embargo, cuando agrego test2() en main() , la MCU procesa el programa muy bien. Me pregunto cómo funciona la asignación de pila para una matriz sin inicializar.

Editar: Finalmente lo descubrí. Verifiqué el código de ensamblaje, en test1 el compilador asignó la memoria, de hecho. Pero en test2 , el compilador optimizó la matriz, por lo que no le asigna memoria.

    
pregunta John G

2 respuestas

3

Tenga en cuenta que 'MCU dejará de ejecutarse' en comparación con 'MCU que aún se está ejecutando' no es un buen criterio para que 'todo esté bien'.

En chips ARM. la pila crece hacia abajo (comienza en alto, cada cuadro de pila anidado ocupa direcciones más bajas), en la mayoría de los casos a partir de la dirección RAM más alta. Cuando la pila crece demasiado para el espacio de pila disponible, sobrescribirá el montón y, a continuación, los datos globales. Si esto es perjudicial para el programa depende. ¿En que? Eso es muy complejo de resolver.

Tenga en cuenta que los 'datos [999]' en sus 'datos de caracteres [1000]' son la dirección más alta dentro de esta variable, por lo que es menos probable que cause un problema. el uso de datos [0] (que se encuentra en la dirección más baja) es más probable que cause un problema.

Nuevamente en ARM, una función que no llama a funciones más profundas podría no usar la pila en absoluto (la dirección de retorno se guarda en un registro, no en la pila).

Entonces, con toda probabilidad, ambos programas son malos, pero es muy difícil predecir si, en la práctica, eso se traduce como "parece funcionar" o "parece detenerse".

    
respondido por el Wouter van Ooijen
0

La asignación de pila para arreglos no inicializados es algo dependiente del compilador. Los compiladores generalmente solo ajustan el puntero de pila en la entrada de la función por el número de bytes que necesitará la función. Si el puntero de pila está en un registro general, el hecho de que los flujos insuficientes probablemente no causará una excepción (pero el intento de usarlo para escribir en una memoria inexistente probablemente lo hará). Pero si el registro del puntero de la pila está dedicado (en hardware), entonces no se puede permitir el desbordamiento.

En el ejemplo de test2() , un compilador inteligente podría notar que solo se necesita uno de los 1000 caracteres "asignados" por el programador, optimizar la generación de la matriz y, en cambio, simplemente presionar "50" (uno o dos bytes) en la pila para la llamada lcdAdjustBacklight() .

Podría decirse que la matriz en test1() también debería haberse optimizado, pero como se ha visto, se asignó a pesar de que no se estaba utilizando.

    
respondido por el JRobert

Lea otras preguntas en las etiquetas