Página siguiente Página anterior Índice general

2.5 Memoria virtual

Objetivos

Entender el espacio de direcciones virtual de los procesos.

Especificación

Determinación de direcciones virtuales

El siguiente programa, imprime en hexadecimal la dirección virtual de diversas partes de un programa. Ejecútelo e intente explicar los resultados. Además mire el tamaño de los distintos segmentos del programa con size.


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

char e1[1000], e2[1000];

char *m = "Hola amigo";

int main(void) {
 char *p1 = malloc(10000);
 char *p2 = malloc(10000);

 printf("main   %10x (%10u)\n", main, main);
 printf("e1     %10x (%10u)\n", &e1, &e1);
 printf("e2     %10x (%10u)\n", &e2, &e2);
 printf("m      %10x (%10u)\n", &m, &m);
 printf("*m     %10x (%10u)\n", m, m);
 printf("p1     %10x (%10u)\n", &p1, &p1);
 printf("p2     %10x (%10u)\n", &p2, &p2);
 printf("*p1    %10x (%10u)\n", p1, p1);
 printf("*p2    %10x (%10u)\n", p2, p2);
 exit(0);
}


Exploración del espacio de direcciones virtuales

El siguiente programa, explora el espacio virtual de las direcciones que un proceso puede leer. Ejecútelo e interprete los resultados.


#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>

typedef enum {si, no, no_sabe, me_da_igual} accesibilidad;

char *dir, *dir0;
accesibilidad acc0;
int tpagina;
jmp_buf estado;

void imprime_rango(char *d1, char* d2, accesibilidad acc) {
   printf("%8x-%8x (%10u-%10u) ", d1, d2, d1, d2);
   if (acc == si) printf("accesible\n"); else printf("inaccesible\n");
}

void informa(accesibilidad acc) {   /* Sólo imprime rangos */
   if (acc0 == no_sabe) acc0 = acc;
   else 
     if (acc != acc0) {
        imprime_rango(dir0, dir-1, acc0);
        dir0 = dir; acc0 = acc;
     }
   dir = dir + tpagina;
   if (dir == NULL) {
      imprime_rango(dir0, dir-1, acc);
      exit(0);
   }
}

void viola(int s) {           /* Procesa violaciones de memoria */
   informa(no);
   signal(SIGSEGV, viola);
   longjmp(estado, 1);
}

int main(void) {
   char dato;
   tpagina = getpagesize();
   acc0 = no_sabe;
   dir = NULL; dir0 = dir;
   signal(SIGSEGV, viola);     /* Etiqueta para volver de violación */
   setjmp(estado);
   for (;;) {
      dato = *dir;              /* Si es inaccesible, no se ejecuta */
      informa(si);
   }
}



Página siguiente Página anterior Índice general