4.5 Cria¸c˜ao de programas
4.5.3 Ligadores (linkers)
Programas capazes de unir parcelas de c´odigo, compiladas separadamente, em um ´unico arquivo de programa execut´avel. Atrav´es de s´ımbolos e po- si¸c˜oes relacionados em tabelas de s´ımbolos geradas pelos compiladores, os ligadores s˜ao capazes de unir trechos de c´odigo existentes em diferentes arquivos objeto em um ´unico arquivo execut´avel.
Os s´ımbolos destas tabelas representam fun¸c˜oes ou estruturas de dados que podem, dentro de certas regras, ser definidas e criadas em certos arqui- vos. Segundo estas mesmas regras, outros arquivos de programa fonte po- dem utilizar-se destas fun¸c˜oes e estruturas sem a necessidade de redefini-las, bastando a indica¸c˜ao adequada de sua existˆencia no exterior destes arquivos fontes. Assim sendo temos:
• M´odulos exportadores
Aqueles onde s˜ao indicadas fun¸c˜oes, estruturas de dados e vari´aveis que ser˜ao utilizadas por m´odulos externos. Utilizam varia¸c˜oes de cl´ausulas extern ou export.
// Exporta¸c~ao de estruturas e vari´aveis em linguagem C // estrutura de dados
typedef struct {
char FuncName[ID LEN]; int Loc;
} FuncType;
// vetor de estruturas exportado extern FuncType FuncTable[]; // vari´avel inteira exportada extern int CallStack[NUM FUNC]; Exemplo 4.2 Declara¸c˜oes de exporta¸c˜ao
• M´odulos importadores
Aqueles onde s˜ao indicadas quais fun¸c˜oes, estruturas de dados e vari´a- veis encontram-se declaradas e implementadas em m´odulos externos. Utilizam varia¸c˜oes de cl´ausulas import ou include.
// Importa¸c~ao de m´odulos em linguagem C #include <vcl\Forms.hpp>
#include <vcl\Classes.hpp> #include <vcl\ Windows.hpp> #include <dos.h>
Exemplo 4.3 Declara¸c˜oes de importa¸c˜ao
Cabe ao ligador a tarefa de unir os arquivos que cont´em estas defini¸c˜oes aos arquivos que as utilizam, gerando disto um ´unico arquivo de programa, como ilustrado na Figura 4.12. A liga¸c˜ao nunca afeta a maneira com que o binding foi ou ser´a realizado, constituindo um elemento neutro dentro da cria¸c˜ao dos programas quando analisada sob o aspecto de modelo de endere¸camento.
Os ligadores participam do binding efetuando a uni˜ao dos espa¸cos f´ısicos dos m´odulos a serem ligados como o programa execut´avel, que determina o espa¸co f´ısico definitivo. Os ligadores n˜ao exercem papel de modifica¸c˜ao ou finaliza¸c˜ao do binding, tarefa que fica a cargo das entidades anteriores (os compiladores) ou posteriores (os carregadores e relocadores).
Figura 4.12: Esquema de compila¸c˜ao em separado e uso de ligador A compila¸c˜ao em separado, com a conseq¨uente uni˜ao posterior dos m´o- dulos produzidos atrav´es de um ligador, tem os seguintes objetivos:
1. Reduzir o tempo de desenvolvimento diminuindo os tempos consumi- dos durante a compila¸c˜ao atrav´es da parti¸c˜ao do programa fonte em
4.5. CRIAC¸ ˜AO DE PROGRAMAS 109 peda¸cos (logicamente divididos e encadeados). Pode-se a partir desta divis˜ao concentrar-se o trabalho em uma das partes de cada vez, que por ser menor toma um menor tempo de compila¸c˜ao. Quando se consi- dera o resultado final, as diversas compila¸c˜oes intermedi´arias durante o desenvolvimento totalizam um menor tempo quando feita por partes do que quando o programa era manuseado por inteiro.
2. Permitir a divis˜ao do trabalho dado que o programa pode ser dividido em partes. Seguindo o mesmo princ´ıpio que o da redu¸c˜ao do tempo de desenvolvimento, as diversas partes podem ser implementadas pa- ralelamente por equipes de 2 ou mais programadores. Assim os totais gastos s˜ao os mesmos quando se consideram a soma dos tempos gastos por cada elemento da equipe ou o custo de tal trabalho, mas tem-se a indiscut´ıvel vantagem de que o desenvolvimento pode ser realizado num prazo bastante inferior dado que as partes podem ser desenvolvi- das em paralelo. Tal divis˜ao requer cuidadoso projeto e especifica¸c˜ao detalhada e consistente das partes do programa.
3. Permitir a padroniza¸c˜ao de c´odigo e a constru¸c˜ao de bibliotecas de fun¸c˜oes e estruturas de dados. Dado que ´e poss´ıvel a compila¸c˜ao de uma parte de um programa contendo apenas fun¸c˜oes (de uso ge- ral ou espec´ıfico) e estruturas de dados associadas, pode-se com isto distribuir-se esta fun¸c˜oes e estruturas sob a forma compilada, ou seja um m´odulo objeto. Outros programadores poder˜ao utilizar este m´o- dulo em seus programas, mas n˜ao poder˜ao alter´a-lo, da´ı obt´em-se a padroniza¸c˜ao segura de fun¸c˜oes e estruturas de dados. Para que isto seja poss´ıvel basta seguir as regras de compila¸c˜ao por partes e acompa- nhar o m´odulo objeto de uma descri¸c˜ao das suas fun¸c˜oes (parˆametros de entrada, resultados retornados) criando-se assim bibliotecas. 4. Permitir o uso de diferentes linguagens de programa¸c˜ao dentro de um
mesmo programa. Considerando a capacidade limitada dos Ligado- res em interpretar as tabelas de s´ımbolos geradas pelos compiladores, se v´arios compiladores, mesmo que de diferentes linguagens de pro- grama¸c˜ao, s˜ao capazes de gerar um formato compat´ıvel de informa¸c˜ao simb´olica, ent˜ao um ligador apropriado ser´a capaz de unir estes di- ferentes m´odulos num ´unico arquivo de programa execut´avel, mesmo que os m´odulos tenham sido escrito em diferentes linguagens. Na ver- dade, durante a implementa¸c˜ao destes m´odulos, devem ser observa- das as conven¸c˜oes de chamada para rotinas externas escritas em ou- tras linguagens espec´ıficas para cada linguagem. Com isto podem ser aproveitadas bibliotecas escritas numa certa linguagem (as bibliotecas matem´aticas do FORTRAN, por exemplo) em programas escritos em outras linguagens (C ou PASCAL). Atrav´es destas t´ecnicas, podem ser melhor exploradas certas carater´ısticas das linguagens em programas
envolvendo v´arias linguagens (C e Clipper, C e DBase, C e SQL, C e PASCAL , VisualBasic e C, etc).