Mirando la secuencia de comandos del vinculador de mi parte (ATMEGA168PD), la región data
tiene un origen definido como que comienza en 0x800060
...
MEMORY
{
text (rx) : ORIGIN = 0, LENGTH = __TEXT_REGION_LENGTH__
data (rw!x) : ORIGIN = 0x800060, LENGTH = __DATA_REGION_LENGTH__
eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = __EEPROM_REGION_LENGTH__
fuse (rw!x) : ORIGIN = 0x820000, LENGTH = __FUSE_REGION_LENGTH__
lock (rw!x) : ORIGIN = 0x830000, LENGTH = __LOCK_REGION_LENGTH__
signature (rw!x) : ORIGIN = 0x840000, LENGTH = __SIGNATURE_REGION_LENGTH__
user_signatures (rw!x) : ORIGIN = 0x850000, LENGTH = __USER_SIGNATURE_REGION_LENGTH__
}
La sección de salida .data
no define explícitamente una dirección, sino que solo se refiere a la región data
...
.data :
{
PROVIDE (__data_start = .) ;
*(.data)
*(.data*)
*(.gnu.linkonce.d*)
*(.rodata) /* We need to include .rodata here if gcc is used */
*(.rodata*) /* with -fdata-sections. */
*(.gnu.linkonce.r*)
. = ALIGN(2);
_edata = . ;
PROVIDE (__data_end = .) ;
} > data AT> text
... sin embargo, la sección de salida .data
termina en la dirección 0x800100
en lugar de 0x800060
...
00800100 l d .data 00000000 .data
Esta resulta ser la dirección correcta para el inicio del segmento .data
en esta parte porque 0x800060-0x8000ff
está reservado para algunos registros y no es un RAM de propósito general.
No hay ningún origen en el script del vinculador que especifique la dirección 0x800100
y no hay parámetros de línea de comando para el vinculador que le dirían este número mágico, específico de la parte. No hay otras secciones de salida en la región data
que puedan empujar la sección de salida .data
en la memoria a la ubicación 0x800100
( .bss
y .noinit
siguen .data
y están relacionadas con ella) .
También he notado que si cambio el nombre de la sección .data
out a cualquier otra cosa, su origen se encuentra al principio de la región data
en 0x800060
como se esperaba. De alguna manera, el enlazador sabe que una sección de salida específicamente llamada .data
debe comenzar específicamente origin 0x800100
en lugar del comienzo de la región especificada en el script del vinculador.
Es como si en algún lugar hubiera .data = 0x800100;
o -Tdata=0x80010
, ¡pero no puedo encontrarlo en ninguna parte!
Mi pregunta es: ¿cómo sabe el vinculador iniciar las direcciones .data
en 0x800100
para esta parte?