EA869 Carregadores e Ligadores Faculdade de Engenharia Elétrica e de Computação (FEEC) Universidade Estadual de Campinas (UNICAMP) Prof. Levy Boccato Introdução • Demos início nas últimas aulas ao estudo dos softwares de sistema. • Softwares de Sistema nada mais são do que programas que gerenciam o hardware de um sistema computacional, definindo quais processos serão executados pela CPU, como a memória será usada e como um programa será instalado, além de estabelecer uma interface simples com o usuário. • O principal software de sistema é o sistema operacional (Ex: Linux, Windows, iOS, Android, entre outros) e será estudado em disciplinas posteriores. • O primeiro tipo de software de sistema estudado foi o montador. • O Montador é responsável por traduzir um programa em linguagem Assembly para Linguagem de Máquina. Por vezes, pode carregar diretamente este programa na memória (Montador Load and Go). Introdução • Vamos rever os passos de todo o processo de tradução de um programa Assembly até seu carregamento completo na memória: PROGRAMA ASSEMBLY AND R1, #3 MOV R1 , R2 SUB R2, #3 MUL R3 , R1, R2 LIGADOR / CARREGADOR MÓDULO OBJETO MONTADOR ESD.´MAIN´.´SD´.0000.001C TXT.0C.2.5E00 TXT.0E.4.06000030 RLD.14.4.´MAIN´ END.00 Definem os endereços adequados, agrupam os módulos de um programa e transferem o mesmo para a memória, dando início à sua execução Esquemas de carregamento MONTAGEM E CARREGAMENTO COMBINADOS PROGRAMA ASSEMBLY AND R1, #3 MOV R1 , R2 SUB R2, #3 MUL R3 , R1, R2 MONTADOR • Neste caso, não há a criação de um módulo objeto. • Quando o código de máquina é gerado pelo montador, ele é colocado diretamente na posição de memória indicada pelo contador de localização. Assim, ao final da montagem, o programa executável já está na memória e o montador simplesmente transfere o controle de execução para a primeira instrução executável do código de máquina gerado. Transfere o programa para a memória Esquemas de carregamento MONTAGEM E CARREGAMENTO COMBINADOS PROGRAMA ASSEMBLY AND R1, #3 MOV R1 , R2 SUB R2, #3 MUL R3 , R1, R2 MONTADOR • Desvantagens: Cada execução do programa requer uma nova montagem (mesmo que não tenha ocorrido qualquer alteração no código). O montador e o programa montado devem obrigatoriamente ocupar a memória principal (ao mesmo tempo). Transfere o programa para a memória Esquemas de carregamento CARREGAMENTO ABSOLUTO PROGRAMA ASSEMBLY AND R1, #3 MOV R1 , R2 SUB R2, #3 MUL R3 , R1, R2 MÓDULO OBJETO MONTADOR ESD.´MAIN´.´SD´.0000.001C TXT.0C.2.5E00 TXT.0E.4.06000030 RLD.14.4.´MAIN´ END.00 • Separa-se o processo de montagem do processo de carregamento e posterior execução do código gerado. CARREGADOR Transfere o programa para a memória Esquemas de carregamento CARREGAMENTO ABSOLUTO • O montador produz um módulo de carregamento que não precisa ser gerado novamente a cada execução. • Além disso, uma vez gerado o módulo de carregamento, o espaço de memória reservado ao programa montador pode ser liberado durante a execução do programa montado. • Tarefas do carregador (absoluto): Obter informações de cada registro que é lido – tipo, endereço inicial de carregamento, quantos bytes deverão ser transferidos e seus conteúdos. Transferir o código para as respectivas posições de memória. Transferir o controle de execução para o endereço especificado no registro do tipo END existente no módulo objeto. Esquemas de carregamento CARREGAMENTO ABSOLUTO • Por sua simplicidade, o esquema de montagem e carregamento absolutos não possui a flexibilidade necessária para uso em sistemas operacionais “modernos”. • Limitações: O programador deve ter acesso direto a posições de memória, especificando exatamente em que regiões de memória o programa e os dados serão carregados. Alternativa: deixar que o software de sistema resolva problemas relacionados ao posicionamento do código por meio de RELOCAÇÃO. Não há suporte para referências a módulos objetos / variáveis globais externas. Alternativa: registrar no módulo objeto possíveis referências a símbolos externos, deixando que o processo de LIGAÇÃO resolva estas referências entre os módulos envolvidos. Tarefas adicionais • O arquivo com o código objeto gerado pelo montador contém parte da informação necessária à execução do programa. • Porém, para que o mesmo possa efetivamente ser executado, é preciso que esse código seja transferido para a memória. • Se o código faz referências a elementos (dados ou rotinas) definidos externamente ao módulo, é preciso integrar essas referências ao código executável. • Tarefas necessárias: Ligação: resolver as referências que tenham sido feitas a dados e/ou rotinas existentes em outros programas. Carregamento: transferir o programa do disco para a memória principal, dando início à sua execução. Esquemas de carregamento CARREGAMENTO COM AJUSTES DE REFERÊNCIAS PROGRAMA ASSEMBLY AND R1, #3 MOV R1 , R2 SUB R2, #3 MUL R3 , R1, R2 MÓDULO OBJETO MONTADOR ESD.´MAIN´.´SD´.0000.001C TXT.0C.2.5E00 TXT.0E.4.06000030 RLD.14.4.´MAIN´ END.00 MÓDULO DE CARGA LIGADOR - Liga todos os segmentos que compõem o programa; - Aloca espaço na memória suficiente para carregar todos os segmentos do programa; - Define o endereço de cada símbolo (rótulo); - Ajusta, no código, as referências a posições de memória. CARREGADOR Transfere o programa para a memória Módulo Objeto MÓDULO OBJETO ESD.´MAIN´.´SD´.0000.001C TXT.0C.2.5E00 TXT.0E.4.06000030 MÓDULO OBJETO RLD.14.4.´MAIN´ END.00 ESD.´MAIN´.´SD´.0000.001C TXT.0C.2.5E00 TXT.0E.4.06000030 RLD.14.4.´MAIN´ END.00 Módulo Objeto • O que é? - Código gerado pelo montador que possui todas as informações necessárias para carregar o código na memória e definir os endereços das variáveis (rótulos). - Possui 4 tipos de registros: MÓDULO OBJETO ESD.´MAIN´.´SD´.0000.001C TXT.0C.2.5E00 TXT.0E.4.06000030 RLD.14.4.´MAIN´ END.00 ESD Dicionário de Símbolos Externos Contém todos os símbolos definidos dentro desse segmento que podem ser referenciados por outros segmentos, além de símbolos que são referenciados, mas não definidos no segmento. ESD. ‘nome do rótulo’ . tipo .end relativo do simb.comprimento SD: indica que o rótulo representa um segmento de código; LD: indica que o rótulo é uma variável do código; Módulo Objeto • O que é? - Código gerado pelo montador que possui todas as informações necessárias para carregar o código na memória e definir os endereços das variáveis (rótulos). - Possui 4 tipos de registros: MÓDULO OBJETO ESD.´MAIN´.´SD´.0000.001C TXT.0C.2.5E00 TXT.0E.4.06000030 RLD.14.4.´MAIN´ END.00 TXT Contém o código de máquina e seu endereço relativo. TXT. end relativo. comprimento. código de máquina Módulo Objeto • O que é? - Código gerado pelo montador que possui todas as informações necessárias para carregar o código na memória e definir os endereços das variáveis (rótulos). - Possui 4 tipos de registros: MÓDULO OBJETO ESD.´MAIN´.´SD´.0000.001C TXT.0C.2.5E00 TXT.0E.4.06000030 RLD.14.4.´MAIN´ END.00 RLD Indicam quais posições (relativas) no segmento deverão ter seu conteúdo ajustado de acordo com os endereços efetivos alocados aos segmentos, indicando também a partir de qual símbolo o conteúdo deverá ser corrigido. RLD. end relativo a ser ajustado.comprimento. símbolo usado para ajuste • Caso o símbolo usado para ajuste esteja definido no próprio módulo, dizemos que foi feita uma relocação. • Caso o símbolo usado para ajuste esteja definido em outro módulo, dizemos que foi feito um ajuste de ligação. Módulo Objeto • O que é? - Código gerado pelo montador que possui todas as informações necessárias para carregar o código na memória e definir os endereços das variáveis (rótulos). - Possui 4 tipos de registros: MÓDULO OBJETO ESD.´MAIN´.´SD´.0000.001C TXT.0C.2.5E00 TXT.0E.4.06000030 RLD.14.4.´MAIN´ END.00 END Indica o fim do segmento/módulo. No caso de o segmento ser aquele que contém a “rotina principal”, este registro também especifica o endereço de início de execução. END. endereço de execução Endereço de execução é o valor que PC irá receber para começar a executar o programa. Caso o módulo não seja o módulo principal, este campo estará vazio. Carregador de Ligação Direta MÓDULO OBJETO • O processo de carregamento com ajuste de referências é executado por um carregador de ligação direta, o qual faz tanto a ligação quanto o carregamento do módulo objeto na memória. ESD.´MAIN´.´SD´.0000.001C TXT.0C.2.5E00 TXT.0E.4.06000030 RLD.14.4.´MAIN´ END.00 • Todo o processo é executado em dois passos: Passo 1 • Aloca espaço em memória, tomando como base a informação sobre o comprimento de cada segmento (registros ESD, tipo SD). Passo 2 • • • Cria a Tabela de Símbolos Globais (GEST) • Como? A partir da leitura dos registros TXT. Tabela que contém o endereço de todos os rótulos • • (símbolos). A partir da leitura dos registros do tipo ESD. Realiza o carregamento do código de máquina na memória – endereço inicial de carregamento (IPLA). Como? Realiza o ajuste do código. Como? A partir da leitura dos registros RLD. • • Inicia a execução do código já carregado. Como? A partir da leitura dos registros END. • Exemplo • Ao final do processamento, o montador gerou os seguintes segmentos: O segmento Main será carregado, seguido, então, pelo segmento PGM. PASSO 1 GEST SÍMBOLO END MAIN 1000 PGM 101C DIGIT 102C PASSO 2 • O IPLA foi definido como 1000. Posição 00 02 04 06 08 0A 0C 0E 1000 1039 0000 0000 0C00 000A 6D02 5E00 0600 1010 0030 13C0 0000 001A 4E75 0000 3039 0000 1020 000E 33C0 0000 0010 4E75 0000 0000 • Exemplo Ao final do processamento, o montador gerou os seguintes segmentos: PASSO 1 GEST SÍMBOLO END MAIN 1000 PGM 101C DIGIT 102C PASSO 2 Posição 00 02 04 06 08 0A 0C 0E 1000 1039 0000 0000 102C 0C00 000A 6D02 5E00 0600 1010 0030 13C0 0000 101A 001A 4E75 0000 3039 0000 1020 102A 000E 33C0 0000 102C 0010 4E75 0000 0000 Ligador • O programa ligador recebe como entrada os diversos módulos a conectar, gerando como saída um único módulo de carregamento. • Desta forma, o carregador recebe o módulo de carga como entrada, transfere seu código para a memória e faz apenas os ajustes de relocação de acordo com o endereço base de memória (IPLA). • A diferença na criação de um módulo objeto preparado para a ligação é que o endereço inicial de carga é considerado como sendo 0. Todos os endereços passam a ser relativos ao início do módulo de carga. A informação para realizar os ajustes de relocação está presente no final do módulo de carregamento e indica quais posições de memória precisam ser atualizadas após alocação . Bibliotecas • Conforme vimos no capítulo de subrotinas, um programa pode solicitar diversas rotinas de serviço durante a sua execução. • Estas rotinas de serviço ajudam a enxugar o código já que evitam que o programador fique repetindo uma mesma parte do código diversas vezes. • Muitas dessas rotinas de serviço podem ser utilizadas por programas diferentes já que, muitas vezes, são rotinas de uso comum que fazem operações elementares: funções de E/S, operações matemáticas, entre outras. • Desta forma, os sistemas operacionais possuem bibliotecas que contém estas rotinas de serviço já em forma de módulo objeto, eliminando a necessidade de montá-las. • A leitura destes módulos objetos podem se dar em dois momentos: Windows Biblioteca DLL (Dynamic Link Library) - O módulo objeto é lido e as referências dos símbolos são todas definidas em tempo de carregamento (antes da execução). Linux Biblioteca ELF (Executable and Linkable Format) - O módulo objeto só é lido se durante a execução seus símbolos forem referenciados (tempo de execução). Bibliotecas Carregamento e ligação dinâmicos: • Em tempo de carregamento: Solução DLL Quando o módulo de carga primário é carregado, todas as referências a módulos externos devem ser resolvidas. Se o módulo externo já está na memória, o mesmo endereço é utilizado. Caso contrário, ele é carregado e seu endereço é definido. Se algum módulo externo não for localizado, a execução é abortada. • Em tempo de execução: Solução ELF Execução tem início com o módulo de carga primário ainda sem a resolução das referências externas. Apenas quando a referência externa for efetivamente necessária é que o sistema faz a resolução. Se o módulo referenciado já está na memória, o mesmo endereço é utilizado. Caso contrário, ele é carregado e seu endereço, uma vez definido, é utilizado na referência. Porém, se a referência externa não é feita (e.g., porque houve um desvio no programa que evitou tal referência), o módulo externo correspondente nem precisa ser carregado. Eventualmente, a aplicação pode executar sem a instalação da biblioteca dinâmica correspondente. Conclusões • O objetivo da disciplina EA869 foi apresentar como se organizam os sistemas de computação digital. • Após uma contextualização histórica, começamos nosso estudo analisando os possíveis problemas que um computador pode ou não pode resolver. • Estudamos a natureza de um problema, sua computabilidade e complexidade. • Em seguida começamos a conhecer como um computador se organiza. Criamos duas arquiteturas e as diferenciamos conforme sua forma de controle: RISC ou CISC. • Definidas as arquiteturas, vimos como as instruções podem ser executadas de forma eficiente (pipeline) e como códigos podem ser escritos de forma mais enxuta (subrotinas). • Seguimos estudando como o processador trata sinais externos – as interrupções – e como se comunica com dispositivos de entrada e saída (periféricos). • Por fim, estudamos os softwares de sistema, os quais são responsáveis por gerenciar o hardware de um sistema computacional. • Falamos brevemente sobre os sistemas operacionais e vimos como um código em Assembly é traduzido em linguagem de máquina por um montador e instalado na memória com auxílio do ligador e do carregador. • Toda esta teoria foi ilustrada na prática com o uso de um simulador do processador ARM. • A última aula desta disciplina se dará no laboratório de computação digital e terá como objetivo prepará-los para a disciplina de EA871, além de vermos na prática como se programa um processador ARM. Fim