167 votes

Pourquoi l' .segment bss nécessaire?

Ce que je sais, c'est que globales et les variables statiques sont stockées dans l' .data segment, et des données non initialisées sont dans l' .bss segment. Ce que je ne comprends pas, c'est pourquoi nous avons segment dédié pour les variables non initialisées? Si une variable non initialisée a une valeur attribuée au moment de l'exécution, la variable existe pas encore dans l' .bss segment?

Dans le programme suivant, a est le .data segment, et b est le .bss segment; est-ce exact? Veuillez me corriger si ma compréhension est erronée.

#include <stdio.h>
#include <stdlib.h>

int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9};
int b[20]; /* Uninitialized, so in the .bss and will not occupy space for 20 * sizeof (int) */

int main ()
{
   ;
}  

Aussi, envisager la suite du programme,

#include <stdio.h>
#include <stdlib.h>
int var[10];  /* Uninitialized so in .bss */
int main ()
{
   var[0] = 20  /* **Initialized, where this 'var' will be ?** */
}

116voto

Lundin Points 21616

La raison est de réduire la taille du programme. Imaginez que votre C programme s'exécute sur un système embarqué, où le code et toutes les constantes sont enregistrées dans la vrai ROM (mémoire flash). Dans ces systèmes, l'initiale de "copier-bas" doivent être exécutées de manière à définir ensemble statique de la durée de stockage des objets, avant main() est appelée. Il sera généralement aller comme ce pseudo:

for(i=0; i<all_explicitly_initialized_objects; i++)
{
  .data[i] = init_value[i];
}

memset(.bss, 
       0, 
       all_implicitly_initialized_objects);

Où .les données et les .bss sont stockées dans la RAM, mais init_value est stocké dans la ROM. Si il avait été l'un segment, puis la ROM devait être rempli avec beaucoup de zéros, en augmentant la taille de la mémoire ROM de manière significative.

En fonction de RAM exécutables fonctionnent de la même façon, même si bien sûr ils n'ont pas de vrai ROM.

Aussi, memset est probable que certains très efficace assembleur en ligne, ce qui signifie que le démarrage de la copie peut être exécuté plus rapidement.

103voto

Jonathan Leffler Points 299946

L' .bss segment est une optimisation. L'ensemble de l' .bss segment est décrit par un seul nombre, probablement 4 octets 8 octets, ce qui donne à sa taille dans le processus en cours d'exécution, tandis que l' .data section est aussi grand que la somme des tailles des initialisé les variables. Ainsi, l' .bss rend les exécutables plus petits et plus rapides à charger. Sinon, les variables qui pourrait être dans l' .data segment avec l'initialisation explicite de zéros; le programme aurait du mal à faire la différence. (Dans le détail, l'adresse des objets en .bss serait probablement différente de l'adresse si elle était dans l' .data segment.)

Dans le premier programme, a serait dans l' .data segment et b serait dans l' .bss segment de l'exécutable. Une fois que le programme est chargé, la distinction devient immatériel. Au moment de l'exécution, b occupe 20 * sizeof(int) octets.

Dans le deuxième programme, var est alloué pour l'espace et l'affectation en main() modifie l'espace. Il se trouve que l'espace pour l' var a été décrit dans l' .bss segment plutôt que de l' .data du segment, mais cela n'affecte pas la façon dont le programme se comporte lors de l'exécution.

25voto

Mihai Points 357

De Langage d'Assemblage étape par Étape: Programmation avec Linux par Jeff Duntemann, concernant l' .les données de la section:

L' .données section contient des définitions de données de initialisé éléments de données. Initialisé les données sont des données qui ont une valeur avant le début du programme en cours d'exécution. Ces valeurs font partie du fichier exécutable. Ils sont chargés en mémoire lorsque l' fichier exécutable est chargé en mémoire pour l'exécution.

La chose importante à retenir à propos de l' .les données de l'article, c'est que l' plus initialisé éléments de données que vous définissez, plus le fichier exécutable sera, et plus il faudra de temps à charger à partir du disque dans la mémoire lorsque vous l'exécutez.

et le .sev section:

Pas tous les éléments de données doivent avoir des valeurs avant le début du programme en cours d'exécution. Lorsque vous êtes en train de lire des données à partir d'un fichier sur disque, par exemple, vous avez besoin d'avoir un place pour que les données puissent aller après elle vient à partir du disque. Tampons de données de ce type sont défini dans la .sev section de votre programme. Vous mettre de côté un certain nombre de octets pour un tampon et de donner de la mémoire tampon d'un nom, mais vous ne dites pas quelles sont les valeurs sont présents dans la mémoire tampon.

Il y a une différence cruciale entre les éléments de données définis dans la .données section et les éléments de données définis dans la .sev section: les éléments de données dans le .les données de la section ajouter à la taille de votre fichier exécutable. Les éléments de données dans l' .sev section ne le font pas. Une mémoire tampon qui prend en hausse de 16 000 octets (ou plus, parfois beaucoup plus) peuvent être définies .sev et ajouter presque rien (50 octets pour la description) vers le fichier exécutable de la taille.

11voto

janneb Points 17303

Eh bien, tout d'abord, ces variables dans votre exemple ne sont pas initialisées; C indique que les variables statiques qui n'est pas autrement initialisé sont initialisées à 0.

Donc, la raison pour .l'option bss est d'avoir de petits fichiers exécutables, de gagner de l'espace et de permettre un chargement plus rapide du programme, le chargeur peut seulement attribuer un tas de zéros au lieu de copier les données à partir du disque.

Lors de l'exécution du programme, le programme chargeur charge .les données et les .sev dans la mémoire. Écrit dans les objets résidant dans .de données ou de .sev donc uniquement de la mémoire, elles ne sont pas vidées dans le binaire sur le disque en tout point.

5voto

Philip Oakley Points 3825

L'article de wikipedia .sev offre une belle explication historique, étant donné que le terme est à partir du milieu des années 1950 (youpi mon anniversaire;-).

Retour dans la journée, tout était précieux, de sorte que toute méthode de signalisation réservés vide de l'espace, a été utile. Cette (.bss) est celui qui a coincé.

.les données des sections sont pour l'espace qui n'est pas vide, au contraire, il devra (vos) la définition des valeurs entré en elle.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X