De https://electronics.stackexchange.com/a/224160/150597 es necesario que el código y los datos se carguen en la RAM antes de la ejecución para la arquitectura Von neumenn. Mientras que en el arco de Harward. ¿el código se puede ejecutar desde la ROM y los datos se pueden cargar desde la RAM?
¿Qué pasa si solo los autobuses se basan en harvard archi? (ARM) y el espacio de direcciones aún está unificado (similar a von neumenn excepto los buses)? En von neumenn, ¿no podemos ejecutar código desde el espacio ROM?
Guau. ¡En realidad no leí todo ese intercambio de EESE! Demasiado para tener que procesar aparte de concentrarse en lo poco que pediste. Así que me centraré en eso.
En las arquitecturas de von Neumann, en términos generales, un programa tiene la siguiente apariencia:
Section Description Access Non-Volatile Size
-----------------------------------------------------------------------
Code Execute Yes Fixed/static
Constants Read Yes Fixed/static
Initialized Data Read/Write Yes Fixed/static
Uninitialized Data Read/Write No Fixed/static
Heap Read/Write No Variable, up
Stack Read/Write No Variable, down
La sección de código puede ser de solo ejecución, como ocurre a menudo con la familia x86. Pero (obviamente) el sistema operativo debe escribirlo, de alguna manera, antes de iniciar el programa. Si se trata de un objetivo integrado e independiente sin un sistema operativo involucrado, generalmente se almacena en la memoria no volátil o se obtiene de la memoria no volátil secundaria (que a menudo se hace sin ningún software adicional utilizando el integrado). en el cargador de arranque ROM que se encuentra en el DSP ADSP-21xx de Analog Devices). Durante la ejecución, puede ser no volátil (si no hay necesidad de modificarlo en tiempo de ejecución) o puede ser volátil (si se requieren modificaciones, como lo que puede suceder con el enlace tardío ).
Como puede ver, es posible que un compilador organice todo el código , las constantes y los datos inicializados para residir en alguna parte de la memoria no volátil. Sin embargo, no es necesario almacenar ninguna de las últimas tres secciones mencionadas en la tabla anterior en la memoria no volátil.
La tabla anterior es casi correcta. Sin embargo, tenga en cuenta que la sección de datos inicializados requiere acceso de lectura y escritura. Dado que casi toda la memoria no volátil no se puede escribir fácilmente, a excepción de FeRAM (o FRAM), casi siempre se almacena en la RAM que se transfiere del almacenamiento no volátil (primario o secundario) a la RAM justo antes de iniciar el código (aparte del código de inicio que normalmente no ve ni escribe). Esto significa que la tabla anterior probablemente debería ser:
Section Description Access Non-Volatile Size
-----------------------------------------------------------------------
Code Execute Yes Fixed/static
Constants Read Yes Fixed/static
Initialized Data Copy Read Yes Fixed/static
Initialized Data Read/Write No Fixed/static
Uninitialized Data Read/Write No Fixed/static
Heap Read/Write No Variable, up
Stack Read/Write No Variable, down
La tabla anterior ahora destaca el hecho de que la sección de datos inicializados debe residir en dos lugares: memoria no volátil (como flash) y memoria volátil (SRAM) y que debe haber un código de inicio que transfiera datos desde el sección de copia de datos a la sección de datos inicializados . Pero recuerde que algunos procesadores, como ciertos MSP430 que están construidos con FRAM, pueden mantener los datos inicializados en su memoria no volátil. Así que cualquiera de las tablas podría ser correcta.
La sección del montón no es estática en tiempo de ejecución. Normalmente, esta sección se configura con un tamaño cero para comenzar y luego crece y se reduce durante la ejecución. Esta es el área utilizada por rutinas como malloc(), por ejemplo. Un diseño simple para el montón lo hace crecer hacia arriba y lejos de la última ubicación de memoria requerida por todas las áreas de datos estáticos y hacia la pila.
La sección de pila tampoco es estática en tiempo de ejecución. Normalmente, esta sección también comienza con un tamaño cero y crece y se reduce durante la ejecución. Esto suele ser donde residen los parámetros de función y las variables "automáticas" locales. El compilador de C también lo utiliza para el almacenamiento temporal, el derrame de registros, etc. Y, por lo general, crece hacia abajo y se aleja de la última ubicación de memoria posible para el programa y hacia el extremo creciente de la sección del montón. De esta manera, hay un área única e invisible de memoria de lectura y escritura, una "tierra de nadie", por así decirlo, entre el montón y la pila, en la que cada sección "se convierte" como una vela encendida en ambos extremos. Si, durante la ejecución, el montón crece en la pila (o viceversa), es probable que el programa no funcione correctamente.
En las arquitecturas de Harvard, existen al menos dos sistemas de memoria diferentes: uno para el acceso al código y otro para el acceso a los datos. Por lo general, existen instrucciones especializadas que permiten leer desde el sistema de memoria de código, tratándolo como datos. Aquí, los detalles se vuelven un poco más complejos que los anteriores.
Cuando se inicia el sistema, el código, las constantes y los datos inicializados deben estar disponibles. Dado que están involucrados diferentes sistemas de memoria, y dado que se debe acceder a todos los datos a través del sistema de memoria de datos, el código de inicio generalmente copia los valores requeridos para la sección de datos inicializados y para la sección de constantes en la SRAM de datos, donde puede tratarse como normal. datos.
Entonces, la tabla de Harvard podría verse así:
Section Description Access Non-Volatile Size
-----------------------------------------------------------------------
Code Execute Yes Fixed/static
Constants Copy Read Yes Fixed/static
Initialized Data Copy Read Yes Fixed/static
Constants Read/Write No Fixed/static
Initialized Data Read/Write No Fixed/static
Uninitialized Data Read/Write No Fixed/static
Heap Read/Write No Variable, up
Stack Read/Write No Variable, down
Aquí, el código de inicio debe transferir la sección de copia de constantes a la sección de constantes y luego también transferir la sección de copia de datos inicializados a la sección de datos inicializados , antes de permitir que el programa continúe.
Para responder directamente a su pregunta sobre poder ejecutar código directamente desde ROM con von Neumann, sí puede. De hecho, a menudo se hace de esa manera. Simplemente graba el código en flash. Eso funciona para ambos tipos, muy bien.
(Y el multiprocesamiento y los subprocesos complican aún más las tablas anteriores).
pjc50
Aimal
pjc50
Aimal
pjc50
Sean Houlihane