Qual é o pano de fundo da segmentação do programa? [fechadas]

0

Cada programa é separado em vários segmentos, como:

  • segmento de código
  • segmento de dados
  • segmento de pilha
  • segmento de heap

Mas quem foi responsável por essa progressão? O compilador e o linker precisam suportar essa conversa para esses segmentos.

  • foi implementado pela primeira vez pelos desenvolvedores do compilador e do linker e os primeiros sistemas operacionais o usaram?

ou

  • foi implementado pela primeira vez pelos desenvolvedores do sistema operacional e os desenvolvedores de compiladores e vinculadores precisaram de um ajuste?
por Jorgos 17.10.2015 / 10:43

1 resposta

1

Isso foi parcialmente baseado no design da CPU. Na década de 1980, a maioria dos computadores tinha uma arquitetura de 16 bits, então um ponteiro poderia acessar um espaço de endereço virtual de 2 16 (65536) bytes. Isto foi, naturalmente, considerado demasiado restritivo. Quando o segmento de código é separado dos outros, você pode ter 2 16 bytes no código (instruções) e 2 16 bytes de dados, o que é menos ruim.

O "espaço de dados" de um programa / processo (usando os termos no sentido mais amplo possível) pode incluir

  • Dados inicializados, incluindo
    • Strings (por exemplo, printf("Hello, world\n"); ),
    • Variáveis inicializadas (por exemplo, int i = 42; ) e
    • Em alguns casos, constantes usadas no código (por exemplo, y = x + 17; ),
  • Variáveis não inicializadas (por exemplo, int j; , char mydata[80]; em contextos estáticos / globais),
  • Memória alocada dinamicamente ( malloc , new ) e
  • Stack (argumentos da função, salvar / restaurar informações e variáveis locais).

Eu posso estar deixando algo de fora, mas os registros não contam (eles são essencialmente um caso especial de variáveis não inicializadas) e a memória compartilhada está além do escopo desta discussão. Note que, do acima exposto, somente os dados inicializados precisam ser salvos no arquivo executável - espaço para variáveis não inicializadas e a pilha é automaticamente alocada pelo SO quando o programa é executado. Então, os compiladores precisavam acompanhar os dados inicializados e variáveis não inicializadas separadamente.

Outra ruga é que o processador Intel 8086 (o trisavô do Pentium) requeria que cada segmento fosse um grande bloco contíguo de memória. O kernel Unix consiste em um grande bloco de código e um grande bloco de dados (dados inicializados e variáveis não inicializadas), mas usa uma pilha separada para cada processo. Portanto, o 8086 exigia a habilidade ter a pilha em um segmento diferente de todos os outros dados.

Há muitas informações sobre isso na web. Por exemplo, na Wikipédia:

por 22.10.2015 / 06:26

Tags