Newsgroup: it.comp.lang.c
Titolo: [semi OT] caricamento ed esecuzione di un programma

suppongo di fare un programmino assembler,
dichiaro qualche variabile ed utilizzo identificatori per le
istruzioni di salto, poi il complilatore sostituisce agli
identificatori gli indirizzi fisici dopodiche' linko e creo
l'eseguibile; a questo punto non mi e' chiara una cosa:
quando il caricatore carica in memoria centrale il mio prog per essere
eseguito, tenendo conto che di volta in volta il prog andra' ad
occupare una porzione di memoria diversa , come si comportano gli ex
identificatori ormai sostituiti da indirizzi?
E' in realta' il caricatore a fare di volta in volta tale operazione?
ciao e grazie
Manfry

...

Credo che sia molto OT, comunque si possono distinguere due casi:
1. Sistemi con Memory Management Unit e paginazione:
Tutti gli indirizzi assoluti (ovviamente si escludono i riferimenti
relativi al program counter) - variabili, jump - sono logici e allocati dal
linker a partire da 0 e non vengono modificati dal loader. Il loader crea
la tabella delle pagine mappando gli indirizzi logici in indirizzi fisici.
Al resto pensa la MMU: un riferimento all'indirizzo virtuale X verra
associato ad una certa pagina (X/4096 = page-index in caso di pagine da 4K)
e la porzione di indirizzo relativa alla pagina (X % 4096) viene sommato
all'indirizzo di base della pagina per ottenere l'indirizzo fisico. Pensa a
tutto, o quasi (vedi memoria virtuale), l'hardware dell'MMU. Unix lavora
piu' o meno cosi'.
2. Sistemi senza MMU
I file eseguibili contengono la lista degli indirizzi rilocabili (sempre
mappati a partire da 0) che vengono "aggiustati" dal loader al momento del
caricamento. Se il loader trova spazio a partire dall'indirizzo fisico
0x10000, tutti i riferimenti assoluti all'indirizzo X verranno modificati
in X+0x1000 (la tabella contiene indirizo logico [X] e l'indirizzo - la
posizione nellla sezione codice del file eseguibile - del riferimento da
rilocare. L'AmigaOs faceva questo lavoro.
Ovviamente c'e' anche il caso del DOS o simili: il programma viene caricato
cosi' com'e', e' il linker che mappa il tutto in modo che funzioni.

identificatori ormai sostituiti da indirizzi?
Agli identificatori non viene sostituito un indirizzo assoluto, ma
relativo.
Questo significa che essi saranno soggetti in fase di caricamento alla
cosiddetta "rilocazione".
Ti faccio un esempio spicciolo :
Se io dichiaro 
struct { int a, b ; } coppia_interi ;
long a ;
short b ;
Supponiamo che il tuo compilatore consideri :
sizeof(short) = 2
sizeof(int)   = 4
sizeof(long)  = 8
Allora assegnera' i seguenti indirizzi (relativi) rispettivamente :
0x00000, 0x00008, 0x00010
Supponiamo che il programma venga caricato in memoria e venga
stabilito a tempo di run-time che i dati inizino all'indirizzo
0xaaaaa, allora gli indirizzi diventano :
0xaaaaa + 0x00000 = 0xaaaaa (indirizzo assoluto)
0xaaaaa + 0x00008 = 0xaaab2
0xaaaaa + 0x00010 = 0xaaaba
In una seconda sessione supponiamo che i dati inizino da 0xbbbbb :
0xbbbbb + 0x00000 = 0xbbbbb
0xbbbbb + 0x00008 = 0xbbbc2
0xbbbbb + 0x00010 = 0xbbbcb
Ovviamente un discorso simile vale per i salti nel codice.

 cosi' com'e', e' il linker che mappa il tutto in modo che funzioni.
Veramente io sapevo che anche per il DOS il loader eseguiva la
rilocazione prima del lancio. Sbaglio?
EMG

 E' in realta' il caricatore a fare di volta in volta tale operazione?
prendiamo il caso degli eseguibili .exe del dos .. (i .com non hanno
rilocazione)
all'inizio del file .exe č memorizzata una tabella creata dal linker
che indica in quale posizione del file ci sono le chiamate che
devonon essere modificate. Il DOS prima di mettere in esecuzione
il programma _aggiunge_ l'indirizzo in cui č caricato il programma
in tutte le posizioni indicate dall'header del file .exe.
quindi il lavoro del linker č creare la tabella nel file .exe, e
generare
chiamate relative. 
-- 
togli .x per rispondermi,NON usare HTML.ICQ 6585343
Linux FAQ 
http://members.bigfoot.com/%7Eranger_rg/
Boycott Microsoft 
http://www.boycott-ms.org/

...

Ouch! Ho messo in giro informazioni false e tendenzione. La prossima volta
saro' piu' attento.
Del resto ero convinto che il DOS non facesse niente, a parte predisporre
CS, DS, ecc., ma cosi' funzionerebbe solo il modello di memoria small. A
ben pensarci deve per forza aggiustare almeno i riferimenti ai segmenti.
Chiedo scusa a tutto il NG.

 
Chiedo ancora scusa: rileggendo il messaggio mi sono accorto che si
potrebbe pensare che stia affermando che il DOS mappa "solo" gli indirizzi
dei segmenti. In realta' non lo so!

dei segmenti. In realta' non lo so!
I file .EXE hanno una tabella di rilocazione quindi immagino siano
sottoposti alla stessa tecnica dei sistemi senza MMU.

 wrote in message
36fb671a...@diesel.cu.mi.it...

Gli EXE per MS-DOS hanno la tabella di rilocazione che contiene gli
indirizzi all'interno del load module (cioe' di cio' che viene caricato in
memoria), delle word a cui il loader dos somma il CS di inizio del load
module stesso, cioe' il segmento da cui ha cominciato a caricare il
programma. La rilocazione di .EXE e' tutta qui!
ciao
donCiccio