Perché differenziare la sezione BSS e COMMON?
Credo che la mia domanda sia diversa da questa . Qui sto chiedendo perché abbiamo bisogno di differenziare questi due, il collegamento risponde solo a quale va a quale.
Lo sappiamo:
La sezione comune è per variabili globali non inizializzate e
La sezione Bss è per le variabili statiche non inizializzate più la variabile globale inizializzata a 0.
Ma perché differenziare la sezione BSS e COMMON? Soprattutto per le variabili globali inizializzate a 0, non possiamo inserirle nella sezione .data che è per le variabili globali inizializzate? L'inizializzazione di una variabile su 0 non è anche un'inizializzazione?
Di seguito è una spiegazione dal mio libro di testo:
in alcuni casi il linker consente a più moduli di definire simboli globali con lo stesso nome. Quando il compilatore sta traducendo un modulo e incontra un simbolo globale debole, ad esempio x, non sa se anche altri moduli definiscono x e, in tal caso, non può prevedere quale delle più istanze di x potrebbe scegliere il linker. Quindi il compilatore rinvia la decisione al linker assegnando x a COMMON. D'altra parte, se x è inizializzato a zero, allora è un simbolo forte, quindi il compilatore può assegnarlo con sicurezza a bss.
Sono davvero confuso, dice “non sa se anche altri moduli definiscono x”, ma come si fa a definire due volte una variabile? È disponibile un codice di esempio per illustrare?
Risposte
.bss viene utilizzata per allocare dati a inizializzazione zero per scopi di ottimizzazione, per consentire
- linker statico per ridurre la dimensione dell'eseguibile (ma non memorizzare gli zeri in esso)
- runtime linker (loader) per velocizzare il processo di caricamento: i dati comuni vengono inizializzati in modo efficiente o mappando una pagina fisica dedicata piena di zeri o inglobando
memsetla memoria all'avvio.
La sezione comune viene utilizzata (su alcune piattaforme, ad esempio Windows ma non ELF) per implementare i cosiddetti "simboli comuni", ovvero simboli che possono essere duplicati in diversi file oggetto ("unità di traduzione"). Quando tale simbolo cade in una sezione comune, il linker statico unirà tutte le definizioni separate (con alcune regole specifiche della piattaforma, ad esempio unisci solo se identico, preferisce la definizione più grande, ecc.).
Su alcuni target le sezioni comuni vengono utilizzate solo per dati non inizializzati (il che li rende in qualche modo simili a .bss) e su altri anche per simboli vaghi . In generale non ci sono ragioni logiche per cui piattaforme diverse hanno fatto scelte diverse riguardo all'uso di sezioni comuni, è puramente storico.
Puoi trovare un po 'di storia dietro i simboli comuni in [articolo di Raymond Chen] (https://devblogs.microsoft.com/oldnewthing/20161024-00/?p=94575).