Estoy usando el compilador xc32 para el microcontrolador microchip pic32.
El tamaño de la memoria del programa (para el arranque, vectores, etc.) es de 1656 bytes.
#include <plib.h> #include <stdio.h> #include <stdint.h> #include <stdarg.h> #include <string.h> //if I use const char array[] for string literal then the size of the program memory increased //equal to the string length(only 12 bytes) //const char array[] = "Hello World"; //program mem size(1668 0x684) bytes //but in this case size increased 28 bytes //const char *array = "Hello World"; //program mem size(1684 0x694) bytes int main { while(1); }con fines de optimización:
¿Cuál es bueno (tanto para la velocidad como para el tamaño)?
Generalmente, la memoria en una MCU se almacena así: ¿Qué reside en los diferentes tipos de memoria de un microcontrolador? Esto significa:
Es muy probable que el literal de cadena "HELLO WORLD" esté almacenado en una sección ROM flash .rodata .
Cuando haces const char array[] = "Hello World"; en el alcance del archivo, la variable de array debe asignarse en .rodata . Por lo tanto, no hay necesidad de asignar el literal de cadena o eso significaría una asignación redundante.
Cuando hace const char *array , declara un puntero y no se asigna en flash, sino en la sección .data de RAM. Entonces, esto significará consumo de RAM y flash. Tenga en cuenta que este puntero es de lectura/escritura; puede asignarlo a otro lugar, pero no puede cambiar los contenidos señalados.
Para asignar el puntero en la ROM flash, debe hacer const char* const array .
En cuanto a por qué obtienes "28 bytes" de algo, no lo sé. No he usado esta parte, pero una breve investigación aquí afirma que podría tener características de Von Neumann, desde el punto de vista de los programadores de C, aunque el núcleo es Harvard. No estoy seguro de a qué se reduce, pero esto es importante ya que las arquitecturas de Harvard pueden necesitar ejecutar algún código de sobrecarga de soporte para acceder a los datos de la ROM flash, lo que a su vez conduce a un tamaño ejecutable ligeramente mayor. Necesitas desmontar si quieres saber los detalles.
Hay diferencias entre sus 3 opciones:
#define STRLIT "HELLO WORLD" define un token de preprocesador: no se genera código ni datos en el ejecutable, pero cada instancia de STRLIT en el código se reemplazará con la cadena literal en el momento de la compilación, lo que puede generar más datos o no.const char arr[] = "HELLO WORLD" define una matriz con nombre de char de tamaño 12 bytes, inicializada y terminada en nulo. Toma 12 bytes en el segmento de datos de solo lectura del ejecutable, lo que puede aumentar el tamaño del ejecutable en 12 bytes o más dependiendo de las restricciones de alineación en el formato del ejecutable.const char *strlit = "HELLO WORLD"; definió un literal de cadena (una matriz constante de 12 bytes de tamaño) y un puntero modificable strlit inicializado para apuntar al literal de cadena. Esto debería usar al menos 4 bytes más en el ejecutable (el tamaño de un puntero en su sistema de destino de 32 bits), pero puede aumentar el tamaño del ejecutable en más de 4 bytes nuevamente dependiendo de las restricciones de alineación en el formato ejecutable.Tenga en cuenta también que, dependiendo de las opciones del compilador, puede haber datos de depuración presentes en el archivo ejecutable.