Sistemas operativos modernos

son muy diferentes del texto del programa: ambos contienen patrones de bits producidos por el compilador que debe cargarse en la memoria cuando comienza el programa. En realidad, la existencia de datos no inicializados es sólo una optimización. Cuando una variable global no recibe en forma explícita un valor inicial, la semántica del lenguaje C esti­ pula que su valor inicial es 0. En la práctica, a casi ninguna variable global se le asigna un va­ lor inicial y, por ende, son 0. Esto podría implementarse teniendo una sección del archivo binario ejecutable exactamente igual al número de bytes de datos, y asignando un valor inicial a todos esos bytes, incluidos los que tienen Ode manera predeterminada. No obstante, para ahorrar espacio en el archivo ejecutable, esto no se hace. En vez de ello, el archivo contiene todas las variables a las que se asignó en forma explícita un valor inicial in­ mediatamente después del texto del programa. Todas las variables no inicializadas están juntas después de las inicializadas, así que lo único que el compilador debe hacer es incluir en el en­ cabezado una palabra que indique cuántos bytes deben asignarse. A fm de hacer más explícito este punto, consideremos otra vez la figura 10-13a. Aquí el tex­ to del programa ocupa 8 KB y los datos iniciahzados también ocupan 8 KB. Los datos no ini­ cializados (BSS) ocupan 4 KB. El archivo ejecutable sólo ocupa 16 KB (texto + datos no inicializados), más un encabezado corto que pide al sistema asignar otros 4 KB después de los datos inicializados y establecerlos a cero antes de comenzar el programa. Con este truco se evi­ ta almacenar 4 KB de ceros en el archivo ejecutable. A diferencia del segmento de texto, el cual no puede cambiar, el segmento de datos sí pue­ de hacerlo. Los programas modifican sus variables todo el tiempo. Además, muchos programas necesitan asignar espacio en forma dinámica durante la ejecución. UNIX maneja esto permitien­ do que el segmento de datos crezca y decrezca a medida que se asigna y libera memoria. Se cuenta con una llamada al sistema, brk, con la que un programa puede establecer el tamaño de su segmento de datos. Así pues, si un programa quiere asignar más memoria, puede aumentar el tamaño de su segmento de datos. El procedimiento de biblioteca de C malloc, que suele utilizar­ se para asignar memoria, emplea esta llamada al sistema en forma intensiva. El tercer segmento es el de pila. En casi todas las máquinas, la pila principia en el tope o cer­ ca del tope del espacio de direcciones virtual y crece hacia abajo (hacia 0). Si la pila crece hasta rebasar el límite inferior del segmento de pila, lo normal es que se presente un fallo de hard­ ware, y el sistema operativo fijará el límite inferior del segmento de pila una página más abajo. Los programas no administran en forma explícita el tamaño del segmento de pila.- Cuando un programa se pone en marcha, su pila no está vacía. Más bien, contiene todas ias variables de entorno (de shell) así como la línea de comandos que se tecleó en el shell pa­ ra invocarlo. De esta manera, un programa puede descubrir sus argumentos. Por ejemplo, cuan­ do se teclea el comando cp origen destino se ejecuta el programa cp con la cadena “cp origen destino” en la pila, lo que le permite averiguar los nombres de los archivos de origen y de destino. La cadena se representa como un arreglo de apuntadores a los símbolos de la cadena, para facilitar su análisis sintáctico. Si dos usuarios están ejecutando un mismo programa, como el editor, sería posible, pero po­ co eficiente, mantener en ia memoria dos copias del texto del programa editor al mismo tiempo.

RkJQdWJsaXNoZXIy MjI4NDcx