Der Grund ist, die Programmgröße zu reduzieren. Stellen Sie sich vor, Ihr C-Programm läuft auf einem eingebetteten System, wo der Code und alle Konstanten im True-ROM (Flash-Speicher) gespeichert sind. In solchen Systemen muss ein anfängliches "Herunterkopieren" ausgeführt werden, um alle statischen Speicherdauer-Objekte zu setzen, bevor main() aufgerufen wird. Es wird normalerweise so aussehen wie dieses Pseudo:
for(i=0; i<all_explicitly_initialized_objects; i++)
{
.data[i] = init_value[i];
}
memset(.bss,
0,
all_implicitly_initialized_objects);
Wobei .data und .bss im RAM gespeichert werden, aber init_value im ROM gespeichert wird. Wenn es ein Segment gewesen wäre, musste das ROM mit vielen Nullen aufgefüllt werden, was die ROM-Größe erheblich erhöhte.
RAM-basierte ausführbare Dateien funktionieren ähnlich, obwohl sie natürlich kein echtes ROM haben.
Außerdem ist Memset wahrscheinlich ein sehr effizienter Inline-Assembler, was bedeutet, dass das Herunterkopieren beim Start schneller ausgeführt werden kann.
Der .bss
Segment ist eine Optimierung. Die gesamte .bss
Segment wird durch eine einzelne Zahl beschrieben, wahrscheinlich 4 Bytes oder 8 Bytes, die seine Größe im laufenden Prozess angibt, während .data
Abschnitt ist so groß wie die Summe der Größen der initialisierten Variablen. Also die .bss
macht die ausführbaren Dateien kleiner und schneller zu laden. Andernfalls könnten die Variablen im .data
stehen Segment mit expliziter Initialisierung auf Nullen; das Programm würde sich schwer tun, den Unterschied zu erkennen. (Im Detail die Adresse der Objekte in .bss
würde sich wahrscheinlich von der Adresse unterscheiden, wenn sie in .data
stünde Segment.)
Im ersten Programm a
wäre in .data
Segment und b
wäre in .bss
Segment der ausführbaren Datei. Sobald das Programm geladen ist, wird die Unterscheidung unwesentlich. Zur Laufzeit b
belegt 20 * sizeof(int)
Bytes.
Im zweiten Programm var
Platz zugeteilt und die Zuordnung in main()
modifiziert diesen Raum. So kommt es, dass das Leerzeichen für var
wurde in .bss
beschrieben Segment anstelle von .data
Segment, aber das hat keinen Einfluss darauf, wie sich das Programm beim Ausführen verhält.