Esta foi a pergunta que um amigo, o Sergio Prallon, fez em uma turma de amigos para a qual ele ensinava C, a qual eu entrei de penetra. E eu respondi da seguinte forma:
"Processo é o programa em execução, e o Programa Executável são os dados necessários para criar um Processo."
É uma resposta curta e simples para algo que é um pouco mais complexo se for ver os detalhes.
Um processo costumava ter, no mínimo, 6 áreas em memória, naquela época. Atualmente deve ter mais uma, pelo menos, que são as bibliotecas compartilhadas, que sempre ficam carregadas em memória, e que todos os programas em execução podem usar.
Um programa fonte é compilado, traduzido, para um Código Objeto Realocável, que no Unix costuma ter a extensão ".o". Depois um Link Editor junta ele a outros Códigos Objetos Realocáveis que estão na biblioteca (que contém as funções que o programador usa, como printf(), strlen() etc, e mais um bando de coisas), e coloca o código de inicialização, gerando assim o Arquivo Objeto Executável, também chamado de Programa Executável.
O Programa Executável contém:
- Cabeçalho descrevendo alguns detalhes dele, e o endereço inicial de execução, por onde deve começar a ser executado;
- O código do programa em uma área chamada de text;
- As variáveis estáticas, criadas a tempo de compilação, que tem um valor inicial, em uma área chamada de data;
- Também no cabeçalho tem o tamanho de uma área chamada de BSS, que conterá as variáveis estáticas que não foram inicializadas, e talvez também as inicializadas com zero. Quando o programa é carregado para a memória, para a formação da imagem do processo em memória, é reservada esta área, logo após a área data, e ela é limpa, zerada.
- A heap, que começa depois da BSS e cresce para cima, conforme é pedida mais memória ao sistema operacional. Quem faz este pedido, se não achou um espaço reaproveitável na heap, é a função malloc() e suas irmãs;
- Um vazio, que não é mapeado. Não existe realmente memória acessível neste espaço, e se houver uma tentativa de acesso a este espaço, ocorrerá o erro segmentation violation;
- E a pilha, stack, que começa no topo e cresce de cima para baixo. Antigamente, nos processadores de 16 bits, existia a chance de colisão entre a stack e a heap, mas atualmente, com o mapeamento de memória maior que a memória física existente, um programa é abortado por falta de memória de swap, ou algum outro evento, antes que isto aconteça.
Alguns compiladores, como o gcc, colocam strings constantes - como o primeiro parâmetro da printf(), que define a formatação de saída - na área de text. Como ela não deve mudar mesmo, não precisa estar na data, que admite alteração (Sob uma opção de compilação, este comportamento pode ser alterado.). A vantagem é que é mais coisa que fica na área de text para ser compartilhada entre processos, economizando mais memória.
Neste ponto já é possível explicar como são alocadas variáveis em memória, especialmente as static, mas isto fica para outro texto.
Nenhum comentário:
Postar um comentário