Para la primera pregunta:
Hay 2kB de SRAM. Hay 32 bytes adicionales de registros de CPU, y otros 64 bytes de registros de E / S (cosas como los registros PORTA / DDRA / etc).
Agregue estos todos hasta obtener 2048 + 32 + 64 = 2144 bytes de memoria direccionable. Convierte eso a hexadecimal y obtienes 0x860, o en términos de dirección 0x000 a 0x85F.
La memoria SRAM en sí misma es el bloque de 2kB de 0x060 a 0x85F.
Para la segunda pregunta:
malloc
usa una llamada "lista de distribución gratuita" que mantiene qué trozos de memoria están disponibles para asignar o reasignar. Esta lista se almacena en la misma SRAM que la memoria que está asignando, y se actualiza sobre la marcha a medida que usa la memoria de asignación.
Cada entrada en la lista gratuita es un puntero de 16 bits, que apunta a la siguiente entrada que forma una cadena, cada entrada hace un seguimiento de dónde está la próxima entrada, y un tamaño de 16 bits que dice qué tan grande es el bloque actual.
Como resultado, cada bloque de memoria asignado mediante malloc
debe tener un tamaño de al menos 4 bytes para almacenar la entrada de la lista. Cuando solicita un solo byte de memoria, tiene que redondear hasta 4 bytes para que cuando esa memoria se desasigne, haya espacio para que se almacene una entrada en la lista.
En lugar de entrar en detalles exactos, el enfoque de listas de distribución se explica en la documentación de avr-libc aquí . La siguiente cita explica la necesidad
La lista de distribución en sí misma no se mantiene como una estructura de datos separada, sino más bien modificando el contenido de la memoria liberada para que contenga punteros que encadenan las piezas. De esa manera, no se requiere memoria adicional para mantener esta lista, excepto por una variable que realiza un seguimiento del segmento de memoria más bajo disponible para la reasignación. Dado que tanto el puntero de la cadena como el tamaño del fragmento deben registrarse en cada fragmento, el tamaño mínimo del fragmento en la lista de distribución libre es de cuatro bytes
Si no puedes entenderlo (el proceso no es obvio de inmediato), no debes preocuparte. Lo más simple que debes recordar es que cada fragmento que malloc
tendrá un tamaño de al menos 4 bytes, incluso si solo quieres 1.
También vale la pena señalar después de un poco de experimentación, la cantidad de memoria asignada parece ser siempre la mayor de 4 bytes, o la cantidad solicitada + 2 bytes. Por ejemplo, si solicita 3 bytes, entonces se asignarán 5 bytes. Si pides 8 bytes obtendrás 10.
En cuanto a por qué se asignan los 2 bytes adicionales, no estoy seguro. No puedo encontrar referencias a esto en la documentación de avr-libc.