¿Por qué cada dirección en un microcontrolador tiene un tamaño de solo 8 bits?

He visto que, en un microcontrolador de 32 bits, cada dirección de memoria contiene solo 8 bits de datos; es lo mismo para un MC de 16 bits también. Para datos de 32 bits, utiliza una combinación de 4 direcciones. ¿Por qué no se puede hacer una dirección para contener datos de 32 bits directamente (haciéndolos 32 bits o 16 cada uno en lugar de 8)?

Depende del bus de datos del microcontrolador. ¿Qué microcontrolador de 32 bits tiene memoria de bytes? ¿Tienes algún ejemplo?
Nuc220V3EAN corteza M0. suponga que la dirección de memoria 0x00 puede contener datos de 1 byte. en MC de 32 bits, la dirección 0x00-0x03 se usa para almacenar datos de 32 bits. ¿Por qué 0x00 no puede tener un ancho de 32 bits?
¿Tienes un enlace a la hoja de datos? Google no devolvió resultados de búsqueda
Simplemente no es cierto, razón por la cual los lenguajes de programación como C y C++ incorporan la posibilidad de que un byte sea mayor a 8 bits. Es solo que la mayoría funciona mejor con bytes de 8 bits, pero existen 9 bits o 18 bits.
@Swanand La versión Motorola MC68008 del microprocesador 68000 vintage de la década de 1980 tenía registros internos de 32 bits pero un bus externo de 8 bits. El National Semiconductors NS32008 era una bestia similar. Estos estaban destinados a sistemas de bajo costo donde se consideraba importante duplicar o cuadriplicar la cantidad de pines necesarios para el bus, la cantidad de dispositivos de memoria costosos y el espacio de la placa.
Es como barras de caramelo. Siguen haciéndolos más pequeños por el mismo precio.
¿Se puede reformular esta pregunta "¿Por qué todas las direcciones están alineadas con 8 bits"?
@FlorianCastellane Esto. Las direcciones no tienen un tamaño de 8 bits (a menos que pueda encontrar un dispositivo con menos de 256 bits de memoria, entonces podrían serlo).
@ArunCheriyan ¿Qué te hace pensar que 0x00 "en sí mismo" no tiene un ancho de 32 bits? De hecho, no tiene un ancho específico. En muchas plataformas, puede leer un valor de 8 bits, un valor de 16 bits, un valor de 32 bits o un valor de 64 bits desde la dirección 0x00.
@jayjay ¿Quieres decir <256 palabras de memoria?

Respuestas (9)

Esta es efectivamente una elección de diseño, no hay ninguna razón por la que tenga que ser así. En los viejos tiempos, cuando los procesadores de productos básicos de gran volumen operaban con valores de 8 bits, el mapeo era más consistente 1:1. Para mantener la coherencia a medida que los diseños evolucionaron hacia los procesadores modernos de 32 y 64 bits, tenía sentido mantener el mapeo anterior de direccionamiento de bytes aunque aumentaran los buses de datos (con una compensación de costos de implementación cambiante). Algunas MCU de 32 bits aún pueden implementar solo buses de datos de 16 bits en alguna memoria, los procesadores de gama alta tendrán 256 bits o más y pueden cargar varios registros centrales en una sola transacción de memoria. Las interfaces anchas son buenas para operaciones de ráfaga o transmisión.

El tamaño pequeño de la memoria direccionable es útil no solo en el caso de manejar valores de bytes en el código, sino también para trabajar con estructuras en la memoria como paquetes de ethernet donde se deben leer o modificar bytes específicos. Con frecuencia, este tipo de operación necesita poder realizar operaciones pequeñas pero de manera muy eficiente.

También existen escenarios donde es necesario operar con datos big-endian, little-endian o mixed endian. Ahora, a menudo hay soporte de hardware dedicado para esto, pero nuevamente, el direccionamiento de bytes de la memoria hará que este tipo de operación sea más eficiente en algunos escenarios.

Es bastante reciente que la cantidad de bits de dirección en un registro ha sido un factor limitante para el espacio de direcciones, por lo que desperdiciar 2 bits para direccionar bytes en lugar de palabras de 32 bits no habría sido una gran preocupación hace 10-15 años (y ahora con punteros de 64 bits, es común implementar direcciones de bytes de 48 o 56 bits de ancho). La enseñanza introductoria de las ciencias de la computación todavía está un poco estancada en la era del mainframe, y no siempre aborda los aspectos de la evolución con mucha claridad. Mucha terminología entró en uso (y definición) en la época en que las arquitecturas de bajo volumen y alto costo (en el sentido más general) comenzaron a complementarse con diseños de procesadores más limitados en recursos y más enfocados en productos básicos.

No he respondido específicamente para MCU, los límites arquitectónicos no son tan claros como podría suponer. Incluso un diseño moderno de MCU desde cero tiene buenas posibilidades de integrarse junto con un procesador de servidor de muchos núcleos, o existir como un solo punto en un conjunto escalable de productos; de cualquier manera, un enfoque consistente para acceder a la memoria es beneficioso para el usuario final que necesita escribir o portar código.

Hice una pregunta en el SE de retrocomputación sobre los tamaños de registro para dar seguimiento a los aspectos históricos de esta pregunta.

Creo que los procesadores con tamaños de palabra más largos son anteriores a los procesadores de 8 bits. Un procesador de 8 bits sería bastante inútil sin un medio eficiente de agregar dos números de varios bytes, y los primeros procesadores no podían manejar eficientemente números más grandes que una sola palabra de máquina.
Trabajé con procesadores de 8 bits lo suficiente como para saber que podían agregar fácilmente números de varios bytes, pero no con una sola instrucción de CPU. Primero, agregue los dos bytes más bajos y obtenga el byte de resultado más bajo y un bit de acarreo separado. Como muchos otros bytes están presentes, agregue los siguientes bytes de entrada y el bit de acarreo del paso anterior, dando el siguiente byte de salida y el siguiente bit de acarreo. Cuando no queden bytes de entrada, convierta el último bit de acarreo en un byte de salida más.
@user6030: ¿No es común tener una instrucción ADC? AVR lo hace (un microcontrolador RISC de 8 bits, por lo que gcc tiene que usar ADC para intylong ), también lo hace x86, también lo hace ARM. Supongo que la mayoría de las CPU de 8 bits lo harían, ya que habría incluso más demanda que en un sistema con registros más amplios. Oh, ¿supercat dice que los primeros procesadores carecían de un ADC eficiente?
Creo que es un punto válido con respecto a la evolución del tamaño del registro (aunque me faltan datos)

Hay algunos DSP (p. ej., TI C54x) que no pueden abordar valores inferiores a 16 bits y algunos DSP de audio utilizan 24 bits. Sin embargo, los valores de 8 bits se usan en casi todo el código de uso general, por lo que todas las CPU de uso general lo admiten.

Y el hecho de que la unidad más pequeña utilizada para las direcciones de memoria sea bytes de 8 bits no significa que esta sea la unidad más grande que se usa realmente en el bus; la mayoría de las CPU usan su tamaño de palabra nativo (16/32 bits) o incluso un tamaño mayor para direccionar la memoria, y cuando usan accesos de byte, extraen automáticamente el byte de la palabra más grande.

Por ejemplo, el bus PCI siempre usa transacciones de 32 bits, pero tiene señales de habilitación de bytes para el acceso que deben ser más pequeñas.

Gracias. ¿Hay algún MC que tenga un nibble de ancho en lugar de un byte en la memoria?
¿Quizás el Intel 4004?
@ArunCheriyan Un ejemplo de una CPU que funcionó con nibbles como la palabra direccionable más pequeña es Saturn : una CPU diseñada por HP y utilizada en sus calculadoras de gama alta en el siglo pasado (la conocida HP48 en particular). Tenía una arquitectura muy inusual (registros de 64 bits, ALU de 4 bits, direcciones de 20 bits, ...).
Otro ejemplo: la unidad direccionable más pequeña para el TMS320C3x de TI es de 32 bits.
@ArunCheriyan: Puede que le interese leer sobre la serie de supercomputadoras Connection Machine de Thinking Machine. Utilizaron microprocesadores de 1 bit (no microcontroladores porque, al igual que la CPU de su computadora portátil, no tenían pines de E/S dedicados). Entonces, los CM solo pudieron procesar un bit a la vez. Pero no se preocupe, su computadora podría tener hasta 64k núcleos.
@dim: Tengo entendido que los chips HP Saturn de 4 bits se fabricaron y usaron en las calculadoras HP hasta mediados de 2003, que es (apenas) este siglo.
@davidcary Oh, bueno... De todos modos, las fechas y la hora nunca han sido mi punto fuerte. Pregúntale a mi esposa sobre sus regalos de cumpleaños y a mi jefe sobre los plazos...

Un microcontrolador de 16 o 32 bits a menudo necesita manipular datos que solo tienen 8 bits de ancho (un byte). Por ejemplo, las cadenas de texto generalmente se almacenan con un solo carácter por byte. Al tener un esquema de direccionamiento de memoria que permite direccionar cada byte individual, el microcontrolador puede procesar eficientemente datos de 8 bits de ancho. Lo que esto significa es que los datos de 32 bits generalmente residen en direcciones que son múltiplos de 4 bytes, por ejemplo, 04, 08, 0C, etc. Pero si la memoria tiene un ancho de 32 bits, el microcontrolador puede leer 32 bits en un ciclo de lectura . Los micro a menudo tienen instrucciones de máquina que pueden operar con datos de diferente longitud, por lo que encontrará que una instrucción de movimiento de datos (MOV) puede tener 3 formas, MOV.B, MOV.W y MOV.L para mover 8, 16 y 32 bits de datos en una instrucción.

La respuesta básica es "porque esa es la longitud de un byte". Con un gran cuerpo de código establecido que hace esa suposición, romperlo causaría todo tipo de problemas.

En los primeros días, no había un cuerpo de código establecido. Los procesadores con frecuencia usarían todo tipo de arquitecturas extrañas, como lo muestran otras respuestas. Sin embargo, cuando salieron los procesadores de 16 bits, había suficiente código asumiendo la disponibilidad de datos de 8 bits, por lo que no hacerlo fácil habría sido una barrera real para la adopción.

Tener una palabra de 32 bits por dirección no presenta ninguna desventaja en la velocidad de la memoria. En un sistema de 32 bits, los 2 bits de dirección inferiores a menudo no van a la memoria. El procesador generalmente leerá la palabra completa de 32 bits y seleccionará (o enmascarará) el byte de 8 bits que necesita dentro de esa palabra. Siempre que su espacio de direcciones pueda almacenar suficientes datos (limitado a 2^32 bytes con un sistema de 32 bits), no se preocupe. De hecho, en muchos procesadores de 16 bits/32 bits se tarda más en procesar con valores de bytes que con valores nativos de longitud de palabra: leer una palabra de 32 bits y descartar parte de esa palabra requerirá claramente una operación adicional. en comparación con solo leer la palabra de 32 bits.

Por el contrario, si tiene un sistema en el que necesita usar la memoria de manera eficiente, entonces necesita poder acceder a bytes individuales. Si no puede, se quedará sin memoria. Con eso en mente, es claramente necesario poder hacer referencia a bytes individuales, por lo que tiene sentido dividir la memoria en bytes.

En efecto. Y luego está la pregunta adicional si un procesador puede manejar los dos accesos distintos necesarios para cargar o almacenar un valor de 32 bits no alineado automáticamente en el hardware, o si eso debe manejarse explícitamente en el software.

Esto es lo que se llama tener memoria direccionable por bytes . Normalmente es algo bueno, a menos que se esté quedando sin espacio de direcciones (por ejemplo, 4 GB con punteros de 32 bits, en lugar de 16 GB con punteros de 32 bits donde cada dirección es una palabra separada de 32 bits).

Tenga en cuenta que el espacio de direcciones puede superar dichos límites si divide las direcciones en partes que caben en un registro cada una. Una vez tuve unas computadoras de 8 bits que alcanzaban los 64 KB de memoria al dividir las direcciones en dos partes guardadas en registros separados, y vi anuncios de computadoras también con procesadores de 8 bits que podían alcanzar 1 MB de memoria al dividir las direcciones en tres partes.
AVR (microcontrolador RISC de 8 bits) hace eso: tres pares de los 32 registros de 8 bits de propósito general se pueden desreferenciar como un puntero de 16 bits. También hay alguna facilidad para combinar eso con otro segmento de 8 bits para obtener direcciones de 24 bits.

Los DSP Shark de 32 bits de Analog Devices tienen 32 bits como la unidad más pequeña de memoria direccionable, por lo que sizeof (int) == sizeof (short) == sizeof (char) == 1 (Sí, tienen caracteres de 32 bits, perfectamente válidos por el estándar C).

Además, cosas como int_8, int_16 y similares no están definidas en , una sorpresa desagradable cuando se transfiere código de otras plataformas.

Probablemente ya se dijo de varias maneras en las otras respuestas. En general hoy, pero no necesariamente históricamente, un byte son 8 bits. La mayoría de las veces tratamos con "memoria direccionable de bytes", lo que significa que lo MÁS PEQUEÑO a lo que podemos acceder con una sola dirección es un byte. Pero eso no significa que sea lo ÚNICO que podamos abordar. Dependiendo de la plataforma, se puede usar una sola dirección para acceder a un byte, media palabra/palabra (16 bits), palabra/doble palabra (32 bits) y así sucesivamente de 64 bits. La instrucción básicamente determina cuál es el tamaño del acceso deseado (8,16,32,64, etc) generalmente en esas unidades 8, 16, 32, 64. Pero eso no es difícil y rápido, "depende".

Además, dependiendo del diseño del procesador y/o del sistema, no hay razón para suponer que el tamaño del acceso es el tamaño de la memoria o el tamaño del acceso más pequeño. Con requisitos cada vez mayores, tiene cada vez menos sentido implementar el sistema de memoria usando el tamaño más pequeño, la computadora en la que está leyendo esto probablemente use un bus de datos de 32 bits de ancho o un bus de datos de 64 bits de ancho para todos los accesos, usted quiere leer un byte, hace una lectura de 64 bits y arroja el resto de los bits, por qué no cuesta nada más mantener el bus así de ancho hasta cerca del núcleo del procesador y el procesador selecciona el carril de bytes correcto. Cuesta más lógica o relojes hacer que el bus sea más estrecho o mover los bytes en los carriles de bytes (a veces se hace). por lo que los carneros internos en un microcontrolador pueden tener 32 bits de ancho, por ejemplo, si eso tiene sentido para el sistema. podría ser 16. Sí, para las escrituras quemas más ciclos, tienes que leer-modificar-escribir en algún lugar a lo largo de la línea. Quiere escribir un solo byte en su PC, en algún lugar ocurre una lectura de 64 bits, y luego en algún lugar se modifica un byte de esos 64 bits, dependiendo de lo que haga después de eso, esos 64 bits pueden volver a funcionar con solo esos 8 bits Sin embargo, a diferencia de lo que había antes, el almacenamiento en caché y su código hacen que esta no sea una regla genérica. Sin embargo, las escrituras son de fuego y olvido, el controlador de memoria puede recopilar la dirección y los datos del procesador y permitir que el procesador siga funcionando mientras finalmente hace la escritura ahorrando relojes, tal vez más relojes que se graban en una lectura-modificación-escritura (si en caché ya),

Incluso hoy en día, hay excepciones a casi todo esto, tal vez haya instrucciones o tipos de acceso en algunos sistemas que son direccionables por bits, hay algunos sistemas donde la dirección está en unidades de algo más que un byte. Un byte no siempre fue de 8 bits y tal vez todavía hay sistemas en ejecución que eso es cierto (solíamos usar octal y un byte de 9 bits, una palabra de 18 o 36 bits tiene mucho sentido para los programadores humanos y diseñadores de chips que piensan en octal, un 8 bits tiene mucho sentido para los pensadores hexadecimales).

Ahora, la computadora en la que está leyendo esto, a pesar de que el bus de datos para ese controlador de dram puede tener 32 o 64 bits de ancho, el módulo de dram en sí mismo probablemente esté compuesto por múltiples partes de 8 bits de ancho, que puede ver fácilmente. Si tiene 8 o 9 chips en un lado, es probable que sea un bus de 64 bits o 72 bits (64 bits más 8 bits de ECC) implementado con partes de 8 bits de ancho. Si tiene 4 o 5 chips en un lado del módulo pero todavía tiene toneladas de pines, entonces tiene un ancho de 32 bits (poco probable en estos días) o 4 de los chips tienen un ancho de 16 bits y si hay un quinto puede ser ser de 16 bits de ancho y solo se usan 8 o es una parte de 8 bits de ancho. También hay partes de 32 bits de ancho, pero las de 8 bits son las más comunes. Una práctica muy común que se remonta a mucho tiempo atrás.

Necesitaríamos saber qué microcontrolador. Dado que menciona 32 bits, es bastante probable (sin información detallada, aunque no podemos decirlo) que la memoria dentro de esa parte tenga 32 bits de ancho, y todos los accesos a ella tengan 32 bits de ancho. las instrucciones probablemente determinarían lo que quiere el programa, que probablemente ofrece un tipo de acceso de 8 bits, 16 bits y 32 bits, los más pequeños en las escrituras requerirían una lectura-modificación-escritura en algún lugar, las lecturas simplemente ignoran los carriles de bytes. Lo mismo ocurre con el flash, aunque las escrituras flash son otro tema. Pero lo más probable es que la memoria flash interna tenga 32 bits de ancho y todas las lecturas se realicen en unidades de 32 bits. Sin embargo, un flash externo, esa es otra historia, lo más probable es que tengan un bit de ancho (spi o i2c), aunque las partes de spi a veces pueden admitir 1, 2 o 4 bits, pero un pin miso es el más común. Internamente se organizan en unidades de bytes, podría ser de 8 bits de ancho o 16 o 32, o quién sabe, sin embargo, los cambia y los aborda en unidades de bytes. con spi puede cambiar entre un byte y toda la memoria en una sola transacción, según el diseño de la pieza flash.

El tamaño de la unidad de memoria direccionable es esencialmente un compromiso entre la cantidad de memoria que puede direccionar y la cantidad de memoria que desperdiciará.

Memoria direccionable . Considere una CPU de 32 bits: si direcciona bytes, puede direccionar hasta 4 GB de memoria. Si aborda bits individuales, esa cantidad se reducirá a 512 MB, y si aborda palabras de 32 bits, tendrá 16 GB. (su pregunta parece sugerir lo último).

Memoria desperdiciada . Si tiene una variable que se puede representar con X bits, y solo puede asignarle unidades de N bits, desperdiciará (N-1)/2 bits en promedio, suponiendo que X > N. Si aborda bits individuales , utilizará la memoria con una eficiencia del 100 % (al menos desde el punto de vista del direccionamiento). Con bytes, desperdiciará 3,5 bits por variable (56 % de eficiencia) y con palabras de 32 bits, desperdiciará 15,5 bits (52 % de eficiencia). Pero empeora: si la mayoría de sus variables son pequeñas (piense en caracteres, booleanos, indicadores de estado), terminará desperdiciando la mayor parte de la memoria si sus unidades direccionables son demasiado grandes.

Por ejemplo, supongamos que el tamaño promedio de una variable es de 8 bits.

  • en una computadora direccionable por bits, podrá asignar con una eficiencia del 100%, lo que le dará 512*1024*1024*100%= 540 millones de variables.
  • en una computadora direccionable por bytes, asignará con una eficiencia del 56 %, lo que le dará 4096*1024*1024*56%= 2400 millones de variables. ¡Eso es casi 5 veces más en comparación con una computadora direccionable por bits! Por supuesto, deberá comprar 8 veces más memoria.
  • en una computadora direccionable de 32 bits, dado que al menos la mitad de sus variables ocuparán menos de 8 bits, se asignarán con una eficiencia inferior al 7% (usando 4,5 bits de 32). En cualquier caso, no obtendrá más de 4.300 millones de variables (ya que solo tiene esa cantidad de direcciones distintas), y menos que eso en realidad. Evitando cálculos complejos, supongo que obtendrá quizás un 20-30% más de almacenamiento útil en comparación con una computadora direccionable por bytes, mientras paga 4 veces el precio de la RAM.

¡También puede obtener procesadores de 1 bit!

El ancho de datos seguirá el ancho del registro (acumulador). este es normalmente el 'ancho del procesador', mientras que el bus de direcciones puede ser diferente (generalmente más ancho), pero técnicamente podría ser más estrecho según el uso.

8, por supuesto, es una potencia de dos números. Tenemos una historia que agradecer por el uso omnipresente de 8 bits y el COSTO/capacidad de la tecnología. Durante mucho tiempo gobernaron los 8 bits, en parte debido al ancho de los buses y la dificultad de hacer registros (y RAM) de más de 8 bits de ancho (no tiene sentido en datos de 16 bits si sus registros son todos de 8 bits). 8 bits es bastante ingenioso y tiene mucho sentido en Hex. 8 bits pueden contener su alfabeto, números, dibujos y caracteres de control (ASCII), o 0 a 255 o +-127 Acceder a más de 256 bytes de datos (bus de direcciones de 8 bits) es fácil con paginación, seleccione la página, luego el byte, por ejemplo 256 páginas de 256 te llevan a 64K (65536). Por lo general, la página cero sería un bloc de notas, ya que sería más rápido acceder, ya que esto no requeriría configurar la página. ¡Mi primera computadora tenía 1k x 8 bits de RAM estática! (la RAM dinámica era más barata, pero necesitaba más hardware para actualizarlo). Con unas pocas banderas (c, nc, z, nz), sumar, restar, girar a la izquierda y a la derecha, puede hacer cálculos bastante complejos en una máquina de 8 bits. ¡No necesitas una unidad aritmética de punto flotante! ¡No súper rápido, pero factible! Muchos de los primeros procesadores podían ser de un solo paso y se usaban con una RAM estática simple que hacía que la depuración fuera realmente fácil; agregando algunos búferes octales y LED rojos tempranos, podría ver cómo cambian los buses de dirección y datos :)