Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Conceptos (repaso):
Tool chain
Herramientas (compilador, ensamblador, etc.) compatibles
Herramientas nativas (native tools)
Crea programas que corren en la computadora que se compila
Host (donde se desarrolla) vs. target (destino)
“Compilador cruzado” (cross-compiler)
Compilador en host produce instrucciones binarias target
Object Files
Compiler
Compiler Executable
Image File
Read-Write
L L Memory (RAM)
in o
Linker
Assembler
Assembler k a
er d
er
Run-Time Library:
Boot
Boot
Operating System Image: Process
Proces
s
main.c main.obj
int aux1,aux2; …
… MOVE R1,(aux1)
aux2 = Compilador CALL fun1
fun1(aux1); …
…
prog..exe
…
MOVE R1,2388
CALL 1547
…
… Memoria
Loader
…
1547 MOVE R1, R5
… 21547
2388 [valor de aux]
… 22388
No necesitan ajustes:
Las direcciones relativas al PC en sistemas con memoria virtual
prog..exe
…
MOVE R1,2388
CALL 1547
…
… Memoria
Loader
…
1547 MOVE R1, R5
… 21547
2388 [valor de aux]
… 22388
Object Files
Read-Write
Memory
Read-Write
Cross-
Cross- (RAM)
Memory
Compiler
Compiler Executable ROM
(RAM)
Image File Image File
Locator
Cross-
Cross- L
Assembler
Assembler o
c
Linker
a
tr o
Re-Entrant Library:
L Read-Only
in Memory
Read-Only
k ROM (ROM)
er Memory
Real-Time Kernel: ROM
"Burner" (ROM)
"Burner"
Tener en cuenta:
Datos persistentes necesitan estar en NVM (non-volatile memory)
Datos modificables necesitan estar en RAM
¿Como sabe el linker/locator dónde poner cada cosa?
El programa se organiza en segmentos que son tratados independientemente
Segmentos
Compilador: crea entidades lógicas conteniendo código o datos
Linker: agrupa segmentos de diferentes códigos objeto
Locator: mapea los segmentos en una ubicación física de memoria
Ejemplo de categorías:
CODE
XDATA
Requerimientos:
Valor inicial (persistente entre reset) → ROM o Flash
Variable (modificable en ejecución) → RAM
Problema:
Valor inicial debe ser copiado en el arranque
Solución:
¿Cómo?
Copiar segmentos “shadow” (con los valores iniciales) de ROM a RAM (más
adelante ejemplo)
¿Quién?
Startup code (código de arranque) ejecutado antes del “main”
El estándar C especifica:
Variables estáticas (non-stack) no inicializadas se inicializan en cero
Requerimientos:
Variable (modificable en ejecución) → RAM
Valor inicial → cero
Solución:
Se realiza un memset (a cero)
Startup code incluye esa rutina
linker/locator
Linker/locator
ROM
z.asm
start
“Compagina” segmentos
x.c x.c
code RAM udata
y.c
“start-code” copia
idatshadow a idata en el
y.c
code udata
arranque
z.asm z.asm
code udata
x.c y.c
idatshadw es copiado a idata idata
string
en el arranque
y.c
idatshadw
****************************************
Mapa:
* *
*
*
MODULE MAP
****************************************
*
*
Usualmente *.map
_STACK_SIZE 0050
*****************************************************************
FILE NAME : C:\temp\Debug\Obj\segment.r43
PROGRAM MODULE, NAME : segment
SEGMENTS IN THE MODULE
Resumen: ======================
DATA16_C
Relative segment, address: 025C - 0265 (0xa bytes), align: 0
Segment part 2. Intra module refs: str1
-----------------------------------------------------------------
DATA16_C
Tipos de segmentos
CODE: código ejecutable
CONST: datos ubicados en ROM
DATA: datos ubicados en RAM
Nomenclatura: nombrebase_sufijo
Nombre base
Por ejemplo: DATA16 (MSP430), NEAR (AVR)
Sufijo (categoría):
Datos no inicializados: N
Datos inicializados a cero: Z
Datos inicializados non-cero: I
Inicializadores para el anterior: ID
Constantes: C
Etc.
ejemplo.c
...
...
int i = 0;
Variables que son inicializadas a
int j = 4;
cero son ubicadas en el
... segmento DATA16_Z
...
Variables inicializadas a valores
distintos de cero son ubicadas en
el segmento DATA16_I y un
segmento de inicialización en
DATA16_ID.
Segmento CSTART
contiene código para:
Arranque (cstartup)
Terminación (exit)
main() {
}//end main
DATA16_I
Relative segment, address: 0200 - 0201 (0x2 bytes), align: 1
Segment part 3. Intra module refs: main
ENTRY ADDRESS REF BY
ej-string.c 0200
str1
-----------------------------------------------------------
char* str1 = "Hola chau"; DATA16_Z
char str2[10]; Relative segment, address: 0202 - 020B (0xa bytes), align: 0
Segment part 5. Intra module refs: main
int main( void ) ENTRY ADDRESS REF BY
{ str2 0202
char* c1; -----------------------------------------------------------
char* c2; c1=str1; CODE
c2=str2; Relative segment, address: 0236 - 0251 (0x1c bytes), align: 1
for(;*c1!=0;c1++,c2++) Segment part 6.
*c2 = *c1; ENTRY ADDRES REF BY
} main S 0236 Seg. part 12 (?cstart)
stack 1 = 00000000 ( 00000002 )
-----------------------------------------------------------
DATA16_ID
Relative segment, address: 02A0 - 02A1 (0x2 bytes), align: 1
Segment part 4. Intra module refs: str1
-----------------------------------------------------------
DATA16_C
Relative segment, address: 0296 - 029F (0xa bytes), align: 0
Segment part 2. Intra module refs: Seg. part 4
char* const str1 = "Hola chau"; Segment part 3. Intra module refs: main
str1 025A
int main( void ) -----------------------------------------------------------
{ DATA16_Z
char* c1; Relative segment, address: 0200 - 0209 (0xa bytes), align: 0
char* c2; c1=str1; Segment part 4. Intra module refs: main
c2=str2; ENTRY ADDRESS REF BY
for(;*c1!=0;c1++,c2++) str2 0200
*c2 = *c1; -----------------------------------------------------------
} CODE
Relative segment, address: 0222 - 023D (0x1c bytes), align: 1
Segment part 5.
ENTRY ADDRESS REF BY
main 0222 Seg. part 12 (?cstart)
stack 1 = 00000000 ( 00000002 )
Alternativas:
Grabarlo en ROM o PROM, y después insertar el chip en la placa
Usar un Emulador ROM
Escribirlo en la memoria flash destino
Usar un “in-circuit emulator”
Misceláneas de programación
Guía de estilo
Técnicas de programación
XP
Programación de a pares (pair programming)
Otros