Baixe o app para aproveitar ainda mais
Prévia do material em texto
ARQUITETURAS RISC E CISC: UM BREVE COMPARATIVO Adriana Paula dos Santos Pasche RESUMO O presente artigo tem como objetivo comparar brevemente duas arquiteturas de processadores criados conforme a característica do seu conjunto de instruções, são elas: CISC (Complex Instruction Set Computer ou Computador com um Conjunto Complexo de Instruções) e RISC (Reduced Instruction Set Computer ou Computador com um Conjunto Reduzido de Instruções). As seções que serão abordadas são necessárias para apresentar o contexto histórico para o surgimento desses processadores, a definição das partes que compõe um sistema computacional e suas características, são fundamentais para a compreensão da evolução dessas arquiteturas. Do mais, serão apresentadas as principais diferenças para em seguida concluir com a comparação das arquiteturas em relação a desempenho, custo e consumo de energia. Palavras-chaves: Arquitetura de processadores, CISC, RISC, Computadores, Tecnologia. 1. INTRODUÇÃO Um dos objetivos de uma arquitetura de processador é fazer com que os programas rodem mais rápido. Isso é o que tona este assunto interessante. Em linhas gerais, as plataformas CISC e RISC sempre sofreram comparações desde que surgiram na década de 70 e 80 respectivamente. Naquela época a comunidade acadêmica e científica tinha uma grande necessidade de melhorar o desempenho dos componentes da CPU que tinha que lidar com diversas instruções e necessitavam, todavia, facilitar a vida dos arquitetos/programadores que escreviam e compilavam em Assembly (linguagem de máquina) pelo menos, milhões de linhas de código. Neste artigo será apresentada uma breve comparação entre as arquiteturas CISC (Complex Instruction Set Computer ou Computador com um Conjunto Complexo de Instruções) e RISC (Reduced Instruction Set Computer ou Computador com um Conjunto Reduzido de Instruções) quanto ao desempenho e ao final pretende-se responder à pergunta: CISC ou RISC, existe um melhor? Para responder a essa pergunta é necessário que seja contextualizado historicamente o surgimento dessas arquiteturas. É importante olhar para estas duas arquiteturas e ver como evoluíram a partir de um conjunto de condições tecnológica que existiram em um determinado momento. Cada uma delas foi uma abordagem ao projeto de máquinas que os arquitetos sentiram ser mais eficientes no uso dos recursos tecnológicos existentes na época. Existiam certas limitações que deveriam ser levadas em consideração a utilização da tecnologia, o que não é retratado mais hoje em dia. Compreender essas limitações e a forma como os arquitetos trabalharam com elas é a chave para entender as arquiteturas CISC e RISC. Sendo assim, uma comparação entre as arquiteturas RISC e CISC requer mais do que apenas uma listagem de suas características de cada uma – requer sua contextualização histórica (Silva e Antunes, 2008). Para entender esse contexto histórico tecnológico, primeiramente é necessário entender como funcionam os compiladores, memória e armazenamento, conjunto de instruções e sua relação com a VLSI e entre um e outro. A partir dessas tecnologias é que os arquitetos começaram a definir qual a melhor arquitetura que seria utilizada para construir máquinas cada vez mais rápidas naquela época. 2. ARQUITETURA COMPUTACIONAL A Arquitetura de computadores é definida como um conjunto de atributos da máquina que um programador deve compreender para que consiga programar o computador específico com sucesso, ou seja, para que consiga compreender o que o programa irá fazer quando da sua execução (Wikipedia,2016) A evolução tecnológica informática foi caracterizada pelo desenvolvimento de computadores com as mais diversas características: CPU, memória e armazenamento, compiladores, entre outros. A definição desses parâmetros e a forma como foram organizados é que irão determinar aspéctos relacionados a qualidade, ao desempenho e a aplicação para qual computador será orientado (Reilly e Ralston, 1993) e essas definições são fundamentais para o entendimento desse artigo. 2.1. CPU CPU é a sigla inglesa de “Central Processing Unit “, ou “Unidade Central de Processamento”. Ela recebe este nome, pois é onde um conjunto de instruções do computador são processadas. Por este motivo, o chip onde ficam localizados os elementos da CPU é chamado de processador. Conjunto de instruções (Set Instruction), são operações que um processador, microprocessador, microcontrolador, CPU ou outros periféricos programáveis suporta, fornece ou disponibiliza para o programador, ou seja, é a representação em mnemônicos do código de máquina, com a finalidade de facilitar o acesso ao componente. Cada componente possui o seu próprio conjunto de instruções, que são fornecidos pelos fabricantes, que também costuma fornecer ou disponibilizar um montador Assembly, que transforma o conjunto de instruções em código de máquina para ser utilizado pelo componente. No caso dos processadores, quando o conjunto de instruções for reduzido leva-o a ter nome de RISC e se forem complexas o nome de CISC. Os processadores têm apresentado uma evolução constante no desempenho, especialmente devido a miniaturização dos componentes. Isso tem permitido produzir processadores mais rápidos, menores e com menor custo, o que não difere muito da época da década de 60, que de acordo com a Lei de Moore, o desempenho e o número de transistores que formam o processador, dobra a cada 18 ou 24 meses. Originalmente, a Lei de Moore (MOORE, 1965) não se referia ao desempenho, mas apenas ao número de transistores em processadores, módulos de memória e outros circuitos. Entretanto, a sofisticação dos circuitos tem uma relação direta com o desempenho. Além disso, novas técnicas de fabricação permitem também aumentar o clock, aumentando a quantidade de instruções por segundo. Originalmente todos os processadores Intel e AMD para PCs eram puramente CISC enquanto que os processadores dos Macintosh e vídeo Games eram RISC. Porém atualmente os processadores Intel e AMD continuam disponibilizando para os programadores um conjunto de instruções CISC, porém internamente são implementados como se fossem RISC, com diversos estágios para transformar as instruções CISC dos programas em instruções semelhantes às instruções RISC para serem executadas pelo hardware. Figura 1 – Processadores Intel características Fonte: http://www.cpu-world.com (2018) 2.2. MEMÓRIA E ARMAZENAMENTO Memória é um termo genérico para designar componentes de um sistema capaz de armazenar dados e programas. O conceito de computador digital binário com programa armazenado (arquitetura de Von Neumman e subsequentes) é sempre baseado no uso de memória, e não existiria sem a utilização destas. É difícil subestimar o efeito que a tecnologia de armazenamento representava no início dos anos 70. Nessa época as memórias utilizavam cariz magnético para armazenar os códigos dos programas, um tipo de memória que além de ser cara também era lenta , porém as coisas melhoraram em termos de velocidade com a chegada da RAM, que é uma memória de semicondutores, volátil, com acesso aleatório, isto é, palavras individuais de memória que são acessadas diretamente, utilizando uma lógica de endereçamento implementada em hardware (WIKIPEDIA, 2016), porém o seu preço ainda era um obstáculo a ser transpassado. Adicionado ao preço da memória, o armazenamento secundário, memória de armazenamento em massa, era caro e lento e por isso, colocar uma quantidade volumosa de códigosna memória desde o armazenamento secundário (não podem ser endereçados diretamente, a informação precisa ser carregada na memória principal antes de poder ser tratada pelo processador.), era por si só, um grande impeditivo ao desempenho. E quanto mais desempenho, melhor. O alto custo da memória e a lentidão do armazenamento secundário foram de certa forma substanciais e incentivadores para fazer com que a escrita de código fosse vista com seriedade. O bom código precisava ser exato e compacto e deveria rodar em um pequeno espaço de memória. Isso representaria uma parte significativa do preço total do sistema, já que a redução do tamanho do código impactava no tamanho da memória e por sua vez, no custo final. Figura 2 – Máquina de Von Neumman Fonte: WIKIPEDIA (2016) 2.3. COMPILADORES Sabe-se que um computador só compreende comandos baseados em linguagem binária, porém, mesmo os programas mais simples exigiram um nível de abstração muito grande do programador, além de desprender muito tempo. Um compilador é um programa (ou conjunto de programas) que traduz um código fonte para uma linguagem de mais baixo nível (Assembly) com uma sequência de instruções a ser executada pelo processador (WIKIVERSIDADE, 2016). Os softwares para os primeiros computadores foram escritos principalmente em Assembly. As linguagens de alto nível de programação (C ou Pascal) não foram inventadas até que os benefícios de ser capaz de reutilizar software em diferentes tipos de CPUs passassem a ser significativamente maiores do que o custo de se escrever um compilador. A capacidade de memória muito limitada nos primeiros computadores também criava problemas técnicos na implementação de um compilador. Posteriormente, vários compiladores experimentais foram desenvolvidos em 1962 o primeiro compilador de - auto hospedagem - capaz de compilar seu próprio código-fonte em uma linguagem de alto nível – foi criado para o LISP por Tim Hart e Levin Mike no Mit (Carvalho,2017). Nesta altura o trabalho de um compilador basicamente era de traduzir o código escrito numa linguagem de alto nível, como C ou Pascal, em assembly. O código assembly era depois convertido para linguagem de máquina por um assemblador (programa que faz a tradução entre a linguagem de montagem e o código de máquina). Essa etapa demandava um longo período de tempo e a expectativa era de que o resultado estivesse no mínimo correto. Para ter um código compacto e otimizado, a solução era programar diretamente em Assembly. 2.4. VLSI A busca por aumento no desempenho dos processadores é constante. Uma das principais evoluções para obter um maior desempenho são através do VLSI (Integração em Grande Escala ou Very Large Scale Integration) que é o processo de criação do circuito integrado (IC) combinado com centenas de milhares de transistores ou dispositivos em um único chip. O VLSI começou na década de 1970, quando tecnologias complexas de semicondutores e comunicação estavam sendo desenvolvidas. O microprocessador é um dispositivo VLSI. Antes da introdução da tecnologia VLSI, a maioria dos Cis tinha um conjunto limitado de funções que eles poderiam executar, era praticamente impossível colocar CPU, ROM, RAM em um único chip. No início dos anos 80 quando começou a desenvolver a arquitetura RISC, um milhão de transistores num único chip já era muito. Devido a falta de recursos (transistores) as máquinas CISC na época tinham as suas unidades funcionais dispersadas por vários chips. Isto gerava um problema pois havia um alto tempo de espera nas transferências de dados entre os chips, o que acarretava em um baixo desempenho. Portanto perseguir uma tecnologia que integrasse tudo em um único chip era o ideal. 3. ARQUITETURA CISC Uma crise no software prevista no início dos anos 70, fez com que um grande número de projetistas e pesquisadores buscassem uma forma de contornar a seguinte situação: Sabendo que o preço do hardware estava cada vez mais barato, surgiu a ideia de mudar a complexidade do cada vez mais caro software transportando-a para o hardware. Simplesmente tornar a vida do programador mais fácil tirando todo o peso do software implementando essa função no hardware, isso reduziria o custo uma vez que o custo do hardware era barato e o tempo gasto pelo programador não. Foi justamente essa ideia que originou a arquitetura CISC (Complex Instruction Set Computer ou Computador com um Conjunto Complexo de Instruções). CISC é uma arquitetura de processadores capaz de executar centenas de instruções complexas diferentes sendo, assim, extremamente versátil. (WIKIPEDIA, 2016) Segue uma lista com algumas das principais razões para se utilizar esse tipo de arquitetura: • Reduzir as dificuldades de escrita dos compiladores; • Redução do custo final do sistema; • Redução no custo do desenvolvimento do software; • Reduzir o tamanho do software do sistema; • Aproximação da linguagem de máquina a linguagem de alto nível (C, Pascal) • Fazer com que os programas escritos em linguagem de alto nível fosses executado mais eficientemente; • Melhorar a compactação do código; • Facilitar a detecção de erros. Seria uma instrução complexa escrita numa linguagem de alto nível que seria então traduzida em uma instrução Assembly, dessa forma os compiladores seriam mais fáceis de escrever, reduziria tempo e esforço do programador e reduziria o custo final. Quanto ao desempenho, os pesquisadores pensaram que ao reduzir o número de instruções que a máquina executa para completar uma determinada tarefa, poderia reduzir o tempo que ela necessita para completar essa mesma tarefa, aumentando assim o seu desempenho. Do ponto de vista de performance, os CISCs têm algumas desvantagens em relação aos RISCs, entre elas a impossibilidade de se alterar alguma instrução composta para se melhorar a performance. O código equivalente às instruções compostas do CISC pode ser escrito nos RISCs da forma desejada, usando um conjunto de instruções simples, da maneira que mais se adequar. Sendo assim existe uma disputa entre tamanho de código X desempenho. Ao reduzir o tamanho do código conseguiam-se dois propósitos: utilizaria uma quantidade menor de memória para armazenar o código; e por outro o tempo de execução era, também, diminuído pois havia menos linha de código para executar. Uma característica da máquina CISC é a micro programação, um conjunto de códigos de instruções que são gravados no processador, permitindo-lhe receber instruções dos programas e executá-las, utilizando as instruções contidas na sua micro programação. Seria como quebrar estas instruções, já em baixo nível, em diversas instruções mais próximas do hardware (as instruções contidas no microcódigo do processador). Como característica marcante esta arquitetura contém um conjunto grande de instruções, a maioria deles em um elevado grau de complexidade. Do ponto de vista mais prático, a vantagem da arquitetura CISC é que ela já tem muitas instruções guardadas no processador, o que facilita o trabalho do programador de linguagem de máquina. (WIKIPEDIA, 2016) 4. ARQUITETURA RISC Já foi dito que os projetos marcados por volta de 1975 incluem as observações que os compiladores restritos da época eram frequentemente incapazes de tirar proveito dos recursos destinados a facilitar a codificação, e que modos de endereçamento complexos levavam muitos ciclos para executardevido aos exigidos acessos à memória principal (WIKIPEDIA, 2018). Nessa época muitas implementações da arquitetura CISC eram tão complexas que eram distribuídas por vários chips, era necessária uma solução capaz de colocar tudo em um único chip, uma solução que fizesse melhor uso dos escassos recursos disponibilizados (transistores). Para que tudo coubesse em um único chip era lógico que muita coisa ficaria de fora, mas era necessário e urgente observar, realizar estudos e descobrir que tipo de situações ocorrem mais frequentemente na execução das aplicações. Teriam que descobrir em que tipo de tarefas o processador se ocupava mais tempo e otimizar essas mesmas tarefas, todos os esforços estavam voltados para a velocidade de execução das tarefas nas quais o processador se ocupa mais, ainda que isso pudesse atrasar outras tarefas não tão frequentes. Com isso, as tarefas mais comuns ficaram cada vez mais rápidas e acabou desenvolvendo uma linha de raciocínio contrária à da arquitetura CISC, a complexidade foi retirada do hardware e passada para o software e isso tudo realizado com o número de instruções reduzidas. Nascia então a arquitetura RISC (acrônimo de Reduced Instruction Set Computer ou Computador com um conjunto reduzido de instruções) é uma linha de arquitetura de processadores que favorece um conjunto simples e pequeno de instruções que levam aproximadamente a mesma quantidade de tempo para serem executadas. Não só em número de instruções foi reduzido, mas também o tamanho das mesmas. Foi decidido que todas as instruções RISC deveriam se possível, levar apenas um ciclo de relógio para terminar a sua tarefa. Foi percebido que tudo poderia ser feito utilizando-se assembly ao invés de microcódigo. Com isso, o microcódigo ficaria de fora e a memória que estava sendo utilizada por este, simplesmente seria usada para armazenar o assembler. Devido a isso é que muitas das instruções de uma máquina RISC correspondem a micro instruções numa máquina CISC. Mais tarde, percebeu-se que a implementação do pipelining só é realmente viável se não tiver que lidar com instruções com diferentes graus de complexidade. A técnica de pipelines permite que várias instruções sejam sobrepostas na execução dentro do processador (PATTERSON; HENNESSY, 2005), executadas em paralelo. Uma instrução é decomposta em várias e distintas tarefas e cada uma delas é executada por diferentes partes do hardware simultaneamente. Isso permite que, enquanto uma instrução esteja sendo decodificada e outra ou outras estejam em execução, no mesmo ciclo de clock. Isso resultaria drasticamente na redução do número médio de ciclos por instrução (CPI – Cycles Per Instruction), reduzindo assim o tempo gasto para sua execução. Segue uma lista com algumas das principais razões para se utilizar esse tipo de arquitetura: • Menor quantidade de Instruções que as máquinas CISC; • Execução Otimizada de chamada de função, os computadores usam mais a memória para executar as tarefas enquanto a RISC utiliza mais registradores da UCP para armazenar parâmetros e variáveis em chamadas de rotinas e funções. • Menor quantidade de modos de endereçamento; • Utilização em larga escala de pipelining. 5. ARQUITETURA RISC X CISC Vários podem ser os temas para a discussão sobre RISC e CISC, um dos quais se refere ao desempenho do processador na execução de um programa, custo e consumo de energia também são itens apontados na discussão uma vez que foram explicados ao longo do contexto histórico apresentado que esses processadores foram desenvolvidos. Iniciamos a comparação falando dos defensores da arquitetura CISC que propunham que instruções mais complexas resultam é código-objeto menor, o que reduz um consumo de memória, com reflexos no custo do sistema. Isso não é correto se considerarmos que uma menor quantidade de instruções nem sempre acarreta menor quantidade de bits (e é a quantidade efetiva de bits que consome menos memória e por consequência, menor o custo). Se cada instrução CISC possuir mais operandos que as instruções RISC e se cada um dos seus operandos ocupar uma boa quantidade de bits na instrução, então poderemos ter um programa CISC maior em bits do que um programa em máquina RISC, apesar de o programa para o processador RISC possuir maior quantidade de instruções. Por exemplo, um programa escrito para rodar em um processador CISC pode gastar 150 instruções de máquina; cada uma das instruções possui código de operação de 8 bits, podendo ser de um, dois, e três operandos. Cada campo operando ocupa 18 bits e ainda há um campo para outras ações, com quatro bits de tamanho. Em média, as instruções têm um total de 50 bits. Um programa para realizar o mesmo problema, escrito para rodar em um processador RISC, pode ter 220 instruções, que em média ocupam 32 bits. As instruções são, em sua esmagadora maioria, de dois operandos, porém os operandos são valores em registradores e, por isso, as instruções não consomem muitos bits para endereçar os dois registradores. O programa para a máquina CISC gastaria 7.500 bits, enquanto o programa para a máquina RISC, mesmo possuindo mais 70 instruções que o processador CISC, consumiria 7.040 bits. Os defensores da arquitetura CISC alegam que estas máquinas executam mais rapidamente os programas escritos em linguagem de alto nível devido à pouca quantidade de códigos binários executáveis. No entanto, o tempo que cada instrução leva para ser executada nem sempre conduz à confirmação dessa assertiva. Máquinas RISC, tendem a executar instruções bem mais rápido por que: 1. as instruções possuem C.Op. com menor quantidade de bits e, portanto, o tempo de decodificação é menor que o das maquinas CISC; 2. as instruções são executadas diretamente pelo hardware e não por um microprograma. Máquinas RISC não são microprogramadas e, assim, tendem a executar as instruções de modo mais rápido. Processadores RISC são também otimizados para operações de uma única tarefa devido ao grande número de registradores que possuem e à grande quantidade de estágios de pipelining. A melhor maneira de obter um bom desempenho dos processadores RISC é executar um programa de teste (um benchmark), o qual possui exatamente esta característica: um grande número de operações similares, em uma única tarefa. Neste ponto, e antes de serem apresentados alguns exemplos de arquiteturas clássicas RISC, deve-se observar que a discussão e o detalhamento de características de processadores que seguem a filosofia CISC e os que seguem a filosofia RISC são atualmente em menos crítica do que foi em anos anteriores, quando havia realmente uma nítida distinção entre ambas. Com o passar do tempo, o avanço da tecnologia em hardware, modificou a visão de alguns projetistas e as adaptações foram surgindo de ambas as partes, de modo que atualmente não se pode afirmar com absoluta certeza que um determinada processador segue rigorosamente a linha RISC nem que outro segue rigorosamente a linha CISC. Os últimos processadores Intel possuem um núcleo de execução RISC, assim como os processadores de 64 bits, Itanium, seguem, em grande parte, as características definidas para um componente RISC. E é bem verdade, que processadores Power sempre possuíram uma quantidade apreciável de instruções, embora todas com largura fixa (WIKIPEDIA, 2018). Tabela 1. RISC e CISC, lado a lado. RISC CISC Múltiplos conjuntos de registradores, muitas vezes superando 256 Único conjunto de registradores, tipicamente entre 6 e 16 registradores Três operandos de registradorespermitidos por instrução (por ex., add R1, R2, R3) Um ou dois operandos de registradores permitidos por instrução (por ex., add R1, R2) Passagem eficiente de parâmetros por registradores no chip (processador) Passagem de parâmetros ineficiente através da memória Instruções de um único ciclo (ex. load e store) Instruções de múltiplos ciclos Controle hardwired (embutido no hardware) Controle microprogramado Altamente paralelizado (pipelined) Fracamente paralelizado Instruções simples e em número reduzido Muitas instruções complexas Instruções de tamanho fixo Instruções de tamanho variável Complexidade no compilador Complexidade no código Apenas instruções load e store podem acessar a memória Muitas instruções podem acessar a memória Poucos modos de endereçamento Muitos modos de endereçamento Preço: mudança da complexidade do Software para o hardware Desempenho: Diminuição do tamanho do código em troca de uma maior CPI. Preço: mudança da complexidade do hardware para o Software. Desempenho: Diminuição do tamanho da CPI em troca de um maior tamanho do código. Características CISC: • Controle microprogramado; • Instruções de dois operandos ADD CX,mem; • Modos registro-registro, registro-memória e memória-registro; • Múltiplos modos de endereçamento à memória, incluindo indexação; • Instruções de largura (tamanho) variável, conforme modo de endereçamento utilizado; • Instruções requerem múltiplos ciclos de máquina para execução, variando também com o modo de endereçamento; • Poucos registros; • Registros especializados. Características RISC: • Controle por hardware; • Pequeno conjunto de instruções; • Todas as instruções têm tamanho fixo; • Execução otimizada de chamada de funções (Call / Return); • Pouquíssimos modos de endereçamento; • Uso intenso de pipeline; • Execução rápida de cada instrução (uma por ciclo do relógio). 6. CONCLUSÃO Ao longo do tempo, as melhorias nas técnicas de fabricação de chips têm melhorado o desempenho de forma exponencial, de acordo com a lei de Moore enquanto melhorias na arquitetura foram relativamente pequenas. Implementações modernas CISC têm implementado muitas das melhorias introduzidas pelo desempenho RISC, tais como transferência de um único clock de instruções simples. Compiladores também se tornaram mais sofisticados e são mais capazes de explorar complexos, bem como as instruções simples sobre arquiteturas CISC, muitas vezes com cuidado otimizar tanto a seleção de instrução e da instrução e da aquisição de dados caches (WIKIPEDIA, 2018). Muitos dos microprocessadores modernos são RISC, por exemplo: DEC Alpha, SPARC, MIPS e PorwerPC, contudo os computadores atuais misturam as duas arquiteturas, criando o conceito de arquitetura hibrida, incorporando os conceitos das duas arquieteturas e a inclusão de um núcleo RISC aos seus processadores. O tipo de microprocessador mais compum em desktops é o x86, é mais semelhante ao CISC do que ao RISC, embora chips mais novos traduzam instruções x86 baseadas em arquitetura CISC em formas basedas em arquitetura RISC mais simples, utilizando prioridade de execução. Concluindo, a partir das informações mencionadas durante todo o artigo vemos que não existe um processador que seja melhor do que o outro mas características melhores em um do que no outro. REFERÊNCIAS http://www.dcc.ufrj.br/~gabriel/arqcomp/RISCxCISC.pdf Acessado em 05/11/2018. http://ww2.deinfo.ufrpe.br/sites/ww2.deinfo.ufrpe.br/files/artigos_aoc/RISCxCISCv2.p df Acessado em 05/11/2018. https://www.ime.usp.br/~song/mac412/oc-risc.pdf Acessado em 05/11/2018. https://www.ebah.com.br/content/ABAAAAuIsAG/risc-x-cisc Acessado em 06/11/2018. https://www.ebah.com.br/content/ABAAABIpIAF/plataformas-cisc-risc Acessado em 06/11/2018. https://www.ebah.com.br/content/ABAAABIpIAF/plataformas-cisc-risc Acessado em 06/11/2018. https://www.ebah.com.br/content/ABAAAfXE4AJ/artigo-arquitetura Acessado em 07/11/2018. https://pt.scribd.com/document/359975539/artigo-arquitetura-risc-cisc-pdf Acessado em 07/11/2018. http://www.inf.ufrgs.br/~flavio/ensino/cmp237/aula02.pdf Acessado em 07/11/2018. http://educapes.capes.gov.br/handle/capes/177823 Acessado em 07/11/2018. https://pt.wikiversity.org/wiki/Introdu%C3%A7%C3%A3o_%C3%A0_Teoria_dos_Co mpiladores/Defini%C3%A7%C3%B5es Acessado em 07/11/2018 https://www.linkedin.com/pulse/o-que-%C3%A9-um-compilador-e-como-ele- funciona-carlos-eduardo Acessado em 07/11/2018.
Compartilhar