12.07.2015 Views

assembly - Projeto Pesquisa - Furb

assembly - Projeto Pesquisa - Furb

assembly - Projeto Pesquisa - Furb

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Trabalho de Conclusão de CursoImplementação de Tipos Abstratos deDados no Ambiente FURBOLAutor: André Luís GarliniOrientador: José Roque Voltolini da Silva


Roteiro• Introdução Objetivos do trabalho• Fundamentação teórica• Desenvolvimento Requisitos do sistema Especificação Implementação Operacionalidade• Conclusões


Trabalho de Conclusão de CursoIntrodução


Introdução• Linguagem de Programação (LP)Serve como meio de comunicação entre o individuo que deseja resolver um problema eo computador escolhido para ajudá-lo na solução.• CompiladoresPara realizar esta comunicação entre o individuo e o computador existem programaschamados de compiladores.• Tipos Abstratos de Dados (TADs)Toda LP apresenta seu próprio conjunto de símbolos e regras para formação deprogramas. Algumas oferecem a possibilidade da criação de TADs definidos pelo usuário.• FURBOLÉ uma LP desenvolvida na FURB que ainda não oferece suporte a TADs.• Objetivo do trabalhoEste trabalho propõe-se a estender o FURBOL, a partir da implementação de Silva(2002), adicionando o suporte a TADs.


Objetivos do trabalho• O objetivo deste trabalho é estender a LP FURBOL.• O objetivo específico do trabalho é adicionar a possibilidade da criaçãode TADs pelos usuários do FURBOL.


Trabalho de Conclusão de CursoFundamentação teórica


Paradigmas de linguagens de programação• Conjunto de características que servem para categorizar um grupo de LPsFonte: Varejão (2004, p. 17).• Imperativo Especificam como o computador deve realizar uma tarefa. Orientação a objetos – Evolução dos TADs.• Declarativo Especificam o que é a tarefa a ser realizada.


Tipos Abstratos de Dados• Conjuntos de valores (atributos) e operações executadas sobre essesvalores (métodos). Exemplo - classe em C++ (sem herança/polimorfismo).• Algumas vantagens Diminui a complexidade dos programas. Abstração. Representação interna fica “escondida” do usuário do TAD.• Quatro tipos de operações Construtoras – inicializam os valores do TAD. Consultoras – usadas para obter informações do TAD. Atualizadoras – permitem a alteração dos valores do TAD. Destrutoras – qualquer atividade de finalização do TAD.


Exemplo de TADclass pilha {private: //** Estes membros são visíveis somente a outros membros//** e amigosint *ptr_pilha;int tam_max;int top_ptr;public: //** Estes membros são visíveis aos clientespilha() { //** Um construtorptr_pilha = new int [ 100 ];tam_max = 99;top_ptr = -1;}~pilha() {delete [] ptr_pilha;}; //** Um destrutorvoid push(int numero) {if (top_ptr == tam_max)cout


Exemplo de um esquema de traduçãoE T RR Op T { print(Op.simbol) } R | ЄT num { print(num.lexval)}Fonte: adaptado de Price e Toscani (2001, p. 88).


<strong>Projeto</strong> de um tradutor preditivo• AlgoritmoEntrada: um esquema de tradução (o esquema deve ser baseado numa gramática apropriadapara análise preditiva).Resultado: código de um tradutor dirigido por sintaxe.Método:1) Para cada não-terminal A, construa uma função que tenha um parâmetro formal para cadaatributo herdado de A e que retorne os valores dos atributos sintetizados de A. Além disso, afunção para A deve ter uma variável local para cada atributo de símbolo gramatical que aparecenas produções de A.2) O código para o não-terminal A deve decidir qual produção usar, baseado no símbolo correnteda entrada. Considerando o lado direito da produção a ser usada, da esquerda para a direita, ocódigo associado deve implementar o seguinte:i) para cada token X, verificar se X é o token lido e avançar a leitura;ii) para cada não-terminal B, gerar uma atribuição c := B(b1, b2, ..., bk), sendo b1, b2, ..., bkvariáveis para os atributos herdados de B, e c a variável para o atributo sintetizado de B;iii) para cada ação semântica, copiar o código correspondente, substituindo cada referência aatributo pela variável desse atributo.Fonte: adaptado de Price e Toscani (2001, p. 110).


Código intermediário• Forma intermediária de código independente de máquina. Código intermediário de três endereços – tipo de código intermediário ondecada instrução faz referência no máximo a três variáveis (endereços dememória).


Geração de código-alvo• Fase final de um compilador.• Gerar código para a máquina alvo (FURBOL - Microprocessador 8088).


Microprocessador 8088• Chip que executa os programas armazenados na memória.• Desenvolvido pela empresa Intel Corporation, sendo uma versão domodelo 8086.• Processador de 16 bits.


Memória do 8088• 2 16 (65.536) - 2 20 (1.048.576)• Esquema de endereçamento de 20 bits• Endereços segmentados Divide o espaço de memória endereçável em segmentos (64 KB). Endereça a memória usando dois registradores. Um para osegmento e outro para o deslocamento (offset) dentro dodeslocamento.• Pilha – Segmento de memória. Algumas utilidades: Salvar valores de registradores que serão utilizados. Salvar endereço de retorno de um método. Parâmetros e variáveis locais de um método.


Registradores do 8088• Quatorze registradores de 16 bitsRegistradores de propósito geralRegistradores de ponteiros e de índicesRegistradores de segmentoRegistrador de ponteiro de instruçãoRegistrador de sinalizadoresAX, BX, CX e DXBP, SP, SI, DICS, DS, SS, ESIPFLAGS• Propósito geral - operações aritméticas e lógicas.• Ponteiros e de índices – deslocamento dentro dos segmentos.• Segmentos – identificam os quatro segmentos endereçáveis em umprograma. CS – segmento de código DS e ES – segmentos de dados SS – segmento de pilha• Ponteiro de instrução – indica o deslocamento da instrução que estásendo executada dentro do segmento de código.• Sinalizadores – indicam resultados da última operação executada.


Algumas instruções do 8088Instrução Formato PropósitoCALL CALL alvo Chamar uma sub-rotina.INT INT tipo Alterar o fluxo de execução do programa, desviando-se para uma rotinade interrupção.MOV MOV destino, fonte Copiar o conteúdo do operando fonte para o destino.POP POP destino Retirar a palavra armazenada no topo da pilha colocando-a noregistrador ou posição de memória especificada por destino.PUSH PUSH fonte Colocar no topo da pilha o valor de fonte.RET RET [dado] Encerrar uma sub-rotina, transferindo o fluxo do processamento para ainstrução seguinte à chamada da sub-rotina. O valor [dado] é opcional.Nele pode-se especificar um valor que após o retorno da sub-rotina seráadicionado ao SP.Fonte: adaptado de Santos e Raymundi (1989, p. 33-92).


FURBOL• Vem sendo desenvolvida por vários integrantes do curso de Ciênciasda Computação da FURB.• Característicasadota o paradigma imperativo. comandos em língua portuguesa. comando de condição e repetição. unidades de programas concorrentes. mecanismo de sincronização da comunicação entre unidadesconcorrentes do tipo semáforo.• Gera código de montagem (<strong>assembly</strong>) compatível commicroprocessadores 8088.• Silva 2002 – unidades de programas concorrentes.


Trabalho de Conclusão de CursoDesenvolvimento


Requisitos do Sistema• Manter os seguintes requisitos do ambiente de Silva (2002): possuir um editor para os arquivos fonte (Requisito Funcional – RF) compilar o código fonte FURBOL, gerando como saída código demontagem (<strong>assembly</strong>) compatível com microprocessadores 8088(RF) emitir mensagens com os resultados da compilação (RF) permitir a visualização do código intermediário de três endereçosgerado (RF)permitir a visualização do código de montagem (<strong>assembly</strong>) gerado(RF) invocar o montador Turbo Assembler e o ligador Turbo Link para ageração de código de máquina executável em microprocessadores8088 (RF)• Permitir a definição de TADs pelos usuários (RF)• Usar esquemas de tradução para representar a semântica (Requisito Não-Funcional - RNF)• Ser implementado usando o ambiente Borland Delphi 7.0 (RNF)


Especificação dos TADs (BNF Extendida)TAD → id Se não Simbolos.SimboloRedeclarado(id.nome) entãoid.simbobj := TSimbolo.Create(id.nome, tsClasse);Simbolos.Instalar(id.simbobj);id.simbobj.TabelaMembros := Símbolos.AbrirEscopo(id.nome);AtributosTADMetodosTAD‘fim’TAD.codigo := MetodosTAD.codigo;TAD.codasm := MetodosTAD.codasm;Simbolos.FecharEscopo;';'


Especificação de um método (BNF Extendida)MetodoTAD → id Se não Simbolos.SimboloRedeclarado(id.nome) entãoid.simbobj := TSimbolo.Create(id.nome, tsMetodo);Simbolos.Instalar(id.simbobj);id.simbobj.TabelaAgregada := Símbolos.AbrirEscopo(id.nome);id.simbobj.TipoMetodo := MetodoTAD.TipoMetodo;ParamOculto := TSimbolo.Create(‘esse’, tsObjeto);Símbolos.Instalar(ParamOculto);ParamFormais‘;’EstruturaDadosCComposto MetodoTAD.codigo := id.nome || ‘proc near’ || CRLF ||CComposto.codigo || CRLF ||‘ret’ || CRLF ||id.nome || ‘endp’;MetodoTAD.codasm := id.nome || ‘proc near’ || CRLF ||‘push bp’ || CRLF ||‘mov bp, sp’ || CRLF ||‘sub sp, ’ || Símbolos.EscopoAtual.LarguraVariaveis || CRLF ||CComposto.codasm ||‘mov sp, bp’ || CRLF ||‘pop bp’ || CRLF ||‘ret’ || Símbolos.EscopoAtual.LarguraParametros + 2 || CRLF ||id.nome || ‘endp’;Símbolos.FecharEscopo;';'


Esboço da tabela de símbolos para um programa em FURBOLprograma Retangulo;classe TRetanguloesquerda, topo, direita, fundo: inteiro;construtor constroi(esquerda, topo, direita, fundo: inteiro);inicioimprime("Construindo um retangulo");esse.esquerda := esquerda;esse.topo := topo;esse.direita := direita;esse.fundo := fundo;fim;procedimento Area;varlargura, altura, area: inteiro;inicioimprime("Area do Retangulo:");largura := direita - esquerda;altura := fundo - topo;area := largura * altura;imprime(area);fim;destrutor destroi;inicioimprime("Destruindo um retangulo");fim;fim;vargRet: TRetangulo;iniciocriarobj(gRet, constroi(0, 0, 20, 20));gRet.Area;destruirobj(gRet, destroi);fim.


Gerencia de memória dos TADs• Registro de ativação dos métodos encontra-se na pilha.• Atributos do objeto encontram-se na heap (memória alocada pelocomando criarobj).classe TRetanguloesquerda, topo, direita, fundo: inteiro;construtor constroi(esquerda, topo, direita, fundo: inteiro);inicioimprime("Construindo um retangulo");esse.esquerda := esquerda;esse.topo := topo;esse.direita := direita;esse.fundo := fundo;fim;procedimento Area;varlargura, altura, area: inteiro;inicioimprime("Area do Retangulo:");largura := direita - esquerda;altura := fundo - topo;area := largura * altura;imprime(area);fim;Atributos – heapParâmetros – pilhaVariáveis locais – pilhadestrutor destroi;inicioimprime("Destruindo um retangulo");fim;fim;


Criação de objetos<strong>Furb</strong>ol<strong>Furb</strong>olclasse TPontox, y: inteiro;construtor constroi(x, y: inteiro);inicioesse.x := x;esse.y := y;fim;fim;varponto1: TPonto;ponto2: TPonto;criarobj(ponto1);(* chamada do construtor é opcional *)<strong>assembly</strong><strong>assembly</strong>ponto1 dw ?ponto2 dw ?1) push ax2) push 43) call criarobj4) mov ponto1,ax5) pop ax Parâmetro do procedimentocriarobj. Tamanho da representação doTAD (atributos).<strong>Furb</strong>olcriarobj(ponto2, constroi(gi, gj));<strong>assembly</strong>01) push ax02) push 403) call criarobj04) mov ponto2,ax05) pop ax06) push gj07) push gi08) push ponto209) push bp10) call TPonto@constroi


Parâmetro oculto esse• Usado para acessar os atributos do objeto.• Similar ao this do C++.• É sempre o primeiro parâmetro do método, portanto sua posição napilha é sempre a mesma.


Chamada de métodos• Parâmetros empilhados da direita para a esquerda.• Em seguida o conteúdo da variável do tipo objeto que está sendoreferenciada também é empilhado (parâmetro oculto esse).01)programa teste;02)03)classe TPonto04) x, y: inteiro;05) procedimento setXY(x, y: inteiro);06) inicio07) esse.x := x;08) esse.y := y;09) fim;10)fim;11)12)var13) ponto1: TPonto;14) gi, gj: inteiro;15)inicio16)(...)17)ponto1.setXY(gi, gj);18)(...)19)fim.<strong>Furb</strong>olponto1.setXY(gi, gj);<strong>assembly</strong>1) push gj2) push gi3) push ponto14) push bp5) call TPonto@setXY


Acesso aos atributos• ES esse• ES:[deslocamento_do_atributo]


Acesso aos atributosclasse TRetangulotopo, esquerda, fundo, direita: inteiro;construtor constroi;iniciotopo := 7;esquerda := 77;fundo := 777;direita := 7777;fim;fim; Deslocamento calculado pelo compiladorconsultado a tabela de simbolos do TAD. Descolamentos 0, 2, 4 e 6, respectivamente<strong>Furb</strong>olconstrutor constroi;iniciotopo := 7;esquerda := 77;(...)fim;<strong>assembly</strong>01) TRetangulo@constroi proc near02) push bp03) mov bp, sp04) sub sp, 005)06) mov ax,707) mov es,word ptr [bp+6]08) mov word ptr es:[0],ax09)10) mov ax,7711) mov es,word ptr [bp+6]12) mov word ptr es:[2],ax13)14) (...)15) TRetangulo@constroi endp


Palavra reservada nulo• Usada para indicar que uma referência a um TAD é inválida(não aponta para um endereço de memória válido).• Para o compilador é equivalente ao valor 0.01)programa teste;02)03)classe TPonto04)(...)05)fim;06)07)var08) ponto: TPonto;09)10)inicio11) (...)12)13) destruirobj(ponto);14) ponto := nulo;15)16) (...)17)fim.<strong>Furb</strong>olponto := nulo;<strong>assembly</strong>1) mov ax,02) mov ponto,ax


Exclusão de objetos<strong>Furb</strong>oldestruirobj(ponto1);( * chamada do destrutor é opcional *)<strong>assembly</strong>1) push ax2) mov ax,ponto13) push ax4) call destruirobj5) pop ax<strong>Furb</strong>oldestruirobj(ponto2, destroi);<strong>assembly</strong>1) push ponto22) push bp3) call TPonto@destroi4) push ax5) mov ax,ponto26) push ax7) call destruirobj8) pop ax


Diagrama de casos de uso


Caso de uso compilar•Descrição: usuário solicita que o programa seja compilado.•Ator principal: usuário.COMPILAR•Cenário principal: compilara) através da interface o usuário escolhe a opção Compilar;b) o sistema compila o programa fonte;c) o sistema invoca o montador Turbo Assembler;d) o sistema invoca o ligador Turbo Link;e) o sistema exibe a mensagem “Programa compilado com sucesso”.•Cenário de exceção: erro de compilação•Caso o programa fonte apresente algum erro o sistema encerra a compilação e apresenta qual é o problema para ousuário.•Cenário de exceção: erro na geração de código de máquina•Caso ocorra algum erro durante a geração do código de máquina o sistema apresenta uma mensagem de erro para ousuário.•Pré-condição: programa escrito em LP FURBOL.•Pós-condição: programa em código de máquina criado.


Diagrama de classes


Diagrama de seqüências para caso de uso compilar


Implementação• Código de Silva (2002) totalmente reaproveitado• Interface não foi alterada• Analisador Léxico – novas palavras reservadas relacionadas aos TADs criarobj destruirobj classe construtor destrutor esse nulo• Analisador Sintático – adaptado para seguir a nova especificação da LP


Implementação do não-terminal TAD01)function TAnalisadorSintatico._TAD(var CodigoAsm: string): string;02)var03) TADName: string;04) MetodosTADCodigo,05) MetodosTADCodAsm: string;06) Simb: TSimbolo;07)begin08) if FLexico.Token = tkIdentificador then begin09)10) if FSimbolos.SimboloRedeclarado(FLexico.Lexema) then11) raise ESinErro.CreateFmt(strErrSinIdentDuplicado, [FLexico.Linha, FLexico.Coluna, 12)FLexico.Lexema]);13)14) TADName := FLexico.Lexema;15)16) FLexico.ProximoToken;17)18) Simb := TSimbolo.Create(TADName, TipoSimboloClasse);19) FSimbolos.Instalar(Simb);20) Simb.TabelaMembros := FSimbolos.AbrirEscopo(TADName);21)22) _AtributosTAD;23)24) MetodosTADCodigo := _MetodosTAD(Simb, MetodosTADCodAsm);25)26) if (FLexico.Token = tkReservada) and (FLexico.Reservada = prFim) then begin27) FLexico.ProximoToken;28) end29) else30) raise ESinErro.CreateFmt(strErrSinTokenEsperado, [FLexico.Linha, FLexico.Coluna, 31)strLexReservadas[prFim]]);32)33) FSimbolos.FecharEscopo;34)35) Result := MetodosTADCodigo;36) CodigoAsm := MetodosTADCodAsm;37)38) if (FLexico.Token = tkEspecial) and (FLexico.Lexema = ';') then begin39) FLexico.ProximoToken;40) end41) else42) raise ESinErro.CreateFmt(strErrSinTokenEsperado, [FLexico.Linha, FLexico.Coluna, 43)';']);44) end45) else46) raise ESinErro.CreateFmt(strErrSinIdentEsperado, [FLexico.Linha, FLexico.Coluna]);47)end;


Operacionalidade do sistema


Interface exibindo código intermediário


Interface exibindo código de montagem


Trabalho de Conclusão de CursoConclusões


Conclusões• O objetivo do trabalho foi alcançado Definir TADs Quatro tipos de operações Declarar referências para os TADs em outras unidades do programa Criar instâncias destes TADs• Outras contribuições consistências e correção de bugs implementação de um procedimento para imprimir inteiros• As ferramentas mostraram-se adequadas• Relevância do trabalho Contribuir com um trabalho de pesquisa realizado pela FURB


Limitações01)programa limitacoes_arrays;02)03)classe TPonto04) x, y: inteiro;05) procedimento setXY(x, y: inteiro);06) inicio07) esse.x := x;08) esse.y := y;09) fim;10)fim;11)12)classe TPilha13) fPilha: matriz; (* não compila *)14)fim;15)16)var17) gPontos: matriz[1..120]: TPonto;18)inicio19) criarobj(gPontos[1]); (* não compila *)20) gPontos[1].setXY(7, 120); (* não compila *)21) destruirobj(gPontos[1]); (* não compila *)22)fim.


Limitações01)programa limitacao_simbolo_nao_definido;02)03)classe TRetangulo04) topo_esquerda,05) fundo_direita: TPonto; (* não compila – Tponto ainda não foi definido *)06)07) (...)08)fim;09)10)classe TPonto11) x, y: inteiro;12)13) construtor constroi(x, y: inteiro);14) inicio15) setXY(x, y); (* não compila – setXY ainda não foi definido *)16) fim;17)18) procedimento setXY(x, y: inteiro);19) inicio20) esse.x := x;21) esse.y := y;22) fim;24)fim;23)24)inicio25) (...)26)fim.


Extensões• Ampliar a LP para oferecer suporte a orientação a objetos.• Criar uma biblioteca com funções de entrada e saída para váriosdispositivos.• Implementar a recuperação de erros de compilação.• Otimizar o código gerado.• Ampliar a LP para permitir a definição de funções.• Gerar código para outras plataformas (microcontroladores, .NET, entreoutros).


Trabalho de Conclusão de CursoFIM

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!