EA960 Conjunto de Instruções Faculdade de Engenharia Elétrica e de Computação (FEEC) Universidade Estadual de Campinas (UNICAMP) Prof. Levy Boccato Introdução Dois conceitos vão permear o estudo dos sistemas computacionais durante este curso, viz., os de arquitetura e organização. Arquitetura: refere-se aos atributos de um sistema que são visíveis a um programador e/ou que possuem impacto direto sobre a execução lógica de um programa. Organização: está associada às unidades operacionais (e suas interconexões) que realizam as especificações arquiteturais. Ou seja, os detalhes do hardware que são transparentes ao programador fazem parte da organização do sistema. 2 Introdução Arquitetura: Conjunto de instruções. Número de bits para representar diferentes categorias de dados (e.g., números e caracteres). Mecanismos de entrada/saída. Modos de endereçamento suportados. Organização: Sinais de controle. Interfaces entre o computador e periféricos. Tecnologia de memória utilizada. 3 Introdução Exemplo: A presença ou não de uma instrução de máquina de multiplicação representa uma decisão de projeto arquitetural. Considerações a respeito de como esta instrução será implementada – se através de uma unidade de multiplicação especial ou por meio de um mecanismo que repetidamente utilize a unidade de adição do sistema – fazem parte do projeto organizacional. 4 Introdução Esta distinção conceitual se mostra importante até os dias de hoje. Alguns fabricantes de computadores oferecem uma família de modelos de computador, todos com a mesma arquitetura, mas com diferenças nas respectivas organizações. Logo, os modelos desta família possuem diferentes características de desempenho e preço. Aproveitamento de software: programas desenvolvidos em um modelo mais barato e mais simples de uma família podem ser utilizados nos modelos mais modernos. Exemplo: IBM System/370 (mainframes). 5 Processador Começaremos nosso estudo lançando os olhares para o processador. 6 Programa Armazenado Fundamento: ideia de programa armazenado. Marca da chamada arquitetura von Neumann (EDVAC) e que apareceu de forma brilhante no famoso trabalho de Alan Turing, intitulado “On computable numbers, with an application to the Entscheidungsproblem”, em 1936. 1º aspecto: instruções são representadas como números à semelhança das variáveis manipuladas. 2º aspecto: programas têm a capacidade de alterar de maneira automática o conteúdo da memória em que estão armazenados. 7 Programa Armazenado Visão geral do processador baseado na ideia de programa armazenado. 8 Processador Mais especificamente, vamos tratar inicialmente de um aspecto arquitetural do processador: o conjunto de instruções – instruction set architectures (ISAs). Instrução de máquina: operação elementar que o processador é capaz de realizar. Vamos considerar a arquitetura MIPS (32 bits) como referência. Atrativo: uso do simulador QtSPIM, disponível em http://spimsimulator.sourceforge.net/. 9 Conjunto de instruções Definir o conjunto de instruções de um processador está longe de ser uma tarefa trivial. Existem várias escolhas que precisam ser balanceadas de maneira adequada a fim de atender múltiplos requisitos. Questões relacionadas: Número de instruções necessárias para executar um programa. Número de ciclos de relógio exigidos por cada instrução. Velocidade do relógio. 10 Conjunto de instruções “The really decisive considerations from the present point of view, in selecting an [instruction set], are more of a practical nature: simplicity of the equipment demanded by the [instruction set], and the clarity of its application to the actually important problems together with the speed of its handling of those problems.” Burks, Goldstine e von Neumann, 1947 11 Conjunto de instruções Operações aritméticas constituem uma porção bastante comum em qualquer ISA. Exemplo: ADD a, b, c # a = (b + c) Quantos operandos uma instrução deve ter? 3 endereços: ADD a, b, c 2 endereços: o resultado é armazenado em um dos operandos. MOVE a, b #a = b ADD a, c #a = (a + c) = (b + c) 1 endereço: somente um operando é explicitado; o resultado é guardado em um local (registrador) específico. LDA b ADD c STA a 12 Conjunto de instruções Importante: a opção de projeto por uma máquina de 1, 2 ou 3 endereços tem implicações no tamanho de cada instrução, no tamanho e inteligibilidade dos programas preparados em linguagem simbólica (Assembly), na velocidade, no custo, na configuração de memória, etc. 13 Conjunto de instruções Que tipos de operandos existem? Registradores: unidades de armazenamento situadas no próprio processador; o acesso é o mais rápido em comparação às demais estruturas de memória. Exemplo MIPS: add $s0, $t0, $t1 Cada registrador é identificado unicamente por um número, o qual é fornecido na(s) palavra(s) de memória que contém a instrução de máquina. Número de registradores: Afeta o comprimento (em bits) dos campos de uma instrução que especificam os operandos. Ao mesmo tempo, a presença de mais registradores significa maior armazenamento em unidades de rápido acesso, não havendo necessidade de usar a memória e/ou pilha (em chamadas de sub-rotinas). OBS: RISC e CISC 14 Conjunto de instruções Que tipos de operandos existem? Memória: contém grandezas ligadas a estruturas de dados mais complexas, e.g., vetores. Para a comunicação com a memória, existem instruções de transferência de dados: MIPS: lw $t0, 8($s3) #carrega em $t0 a palavra armazenada no endereço de memória $s3 + 8 MIPS: sw $t0, 16($s2) #grava o conteúdo de $t0 no endereço dado por $s2 + 16 Arquitetura load/store: as instruções somente lidam com valores que estejam nos registradores e sempre armazenam resultados em algum registrador, como é o caso do MIPS. 15 Conjunto de instruções Que tipos de operandos existem? Como o dado será armazenado na memória? Registrador Registrador Memória Memória Big-endian Little-endian MIPS 16 Conjunto de instruções Que tipos de operandos existem? Constantes / Imediatos: valores fixos (numéricos). Exemplo MIPS: addi $s3, $s3, 10 $s3 = $s3 + 10 17 Conjunto de instruções MIPS Utiliza instruções com 3 endereços. As instruções possuem tamanho fixo de 32 bits. Dispõe de um banco de 32 registradores de 32 bits. OBS: Há também o program counter, PC, que contém o endereço da instrução atual. 18 Conjunto de instruções MIPS Endereço: 32 bits – referente a byte. Logo, se o registrador $t1 contém o endereço da primeira palavra de um vetor, a próxima palavra está no endereço $t1 + 4. Estas escolhas, bem como as que veremos mais adiante, favorecem a regularidade do projeto deste processador, contribuindo também para uma maior simplicidade do hardware (e.g., para a decodificação das instruções). 19 Conjunto de instruções Como representar computador? as instruções em um Lembrar: cada instrução também é armazenada como uma série de sinais elétricos binários (e.g., 0 V ou 5 V). Como interpretar esta sequência de dígitos binários? op rs rt rd shamt funct 6 bits 5 bits 5 bits 5 bits 5 bits 6 bits op – opcode: identifica a operação básica. rs – primeiro operando (registrador). rt – segundo operando (registrador). rd – registrador de destino (resultado). shamt – shift amount: define o tamanho do deslocamento. funct – function: especifica a versão ou variante da operação indicada em op. TOTAL: 32 bits – mesmo tamanho de uma palavra de memória. Formato R 20 Conjunto de instruções Como representar computador? as instruções em um Lembrar: cada instrução também é representada como uma série de sinais elétricos binários (e.g., 0 V ou 5 V). Como interpretar esta sequência de dígitos binários? op rs rt Constante / Endereço 6 bits 5 bits 5 bits 16 bits Formato I Limitado a valores entre ± 215 21 Conjunto de instruções Como representar computador? as instruções em um A opção por múltiplos formatos de instrução tende a complicar a construção do hardware e a decodificação. No entanto, algumas partes de uma instrução têm suas características preservadas, reduzindo a complexidade. Os três primeiros campos dos formatos I e R são idênticos. O tamanho do quarto campo do formato I ocupa o mesmo número de bits que os últimos três campos do formato R. As instruções continuam tendo o mesmo tamanho (32 bits), ainda que existam diferentes formatos possíveis. 22 Conjunto de instruções MIPS (até o momento): 23 Conjunto de instruções Operações lógicas também são bastante frequentes nas ISAs. Operação C MIPS Shift left << sll Shift right >> srl Bitwise AND & and, andi Bitwise OR | or, ori Bitwise NOT ~ nor Para manter consistência com o formato de 3 endereços. Adotam o formato R e utilizam o campo shamt para informar o tamanho do deslocamento (quando pertinente). 24 Conjunto de instruções Um computador se distingue de uma simples calculadora por causa de sua habilidade de tomar decisões. “The utility of an automatic computer lies in the possibility of using a given sequence of instructions repeatedly, the number of times it is iterated being dependent upon the results of the computation This choice can be made to depend upon the sign of a number (zero being reckoned as plus for machine purposes). Consequently, we introduce an [instruction] (the conditional transfer [instruction]) which will, depending on the sign of a given number, cause the proper one of two routines to be executed.” Burks, Goldstine e von Neumann, 1947 25 Conjunto de instruções Instruções de desvio condicionais / incondicionais: beq reg1, reg2, L1 Desvia para a posição de memória rotulada como L1 caso o conteúdo dos registradores seja igual. bne reg1, reg2, L1 Desvia para a posição de memória rotulada como L1 caso o conteúdo dos registradores não seja igual. j L1 Desvia diretamente para a posição de memória indicada por L1. 26 Conjunto de instruções Instruções de desvio condicionais / incondicionais: Complemento: slt $t0, $s3, $s4 – $t0 recebe 1 se $s3 < $s4. Esta instrução pode ser usada, juntamente com as anteriores, para realizar saltos relativos às condições: menor, menor ou igual, maior e maior ou igual. Solução de compromisso para evitar o acréscimo de complexidade que acompanha instruções como blt, ble, bgt e bge. Também há a instrução slti, para a comparação com uma constante, bem como as versões sltu e sltiu, considerando variáveis sem sinal (unsigned). 27 Conjunto de instruções Outro recurso bastante utilizado por programadores / compiladores está associado à noção de sub-rotina. Passos para a execução de uma sub-rotina: 1) 2) 3) 4) 5) 6) Passagem de parâmetros. Transferência do controle de execução. Aquisição dos recursos de armazenamento necessários para o procedimento. Realização da tarefa desejada. Armazenamento do resultado em local acessível ao programa que chamou a sub-rotina. Retorno à execução do programa original. 28 Conjunto de instruções Convenção MIPS: $a0 - $a3: quatro registradores para a passagem de parâmetros. $v0 - $v1: dois registradores para retorno de resultados. $ra: registrador de endereço de retorno. Instruções adicionais: jal ROTINA Desvia a execução para o endereço indicado por ROTINA e automaticamente salva o endereço de retorno (PC + 4) em $ra. jr $ra Desvia para a posição de memória indicada pelo registrador $ra – implementa o retorno da sub-rotina. 29 Conjunto de instruções E se o número de registradores para parâmetros e/ou resultados não for suficiente? Além disso, a sub-rotina pode modificar qualquer registrador sem maiores problemas? A arquitetura MIPS prevê a existência de uma pilha, a qual pode ser usada como resposta a estas duas questões. Endereços maiores Área ocupada $sp – stack pointer: aponta para a posição na pilha mais recentemente ocupada. $sp Palavra Endereços menores Tradicionalmente, a pilha cresce em direção aos endereços menores. Por isso: Para guardar um valor na pilha, é preciso: (1) decrementar $sp por 4; (2) colocar na posição 0($sp) o valor desejado. 30 Conjunto de instruções E se o número de registradores para parâmetros e/ou resultados não for suficiente? Além disso, a sub-rotina pode modificar qualquer registrador sem maiores problemas? Exercício: Rotina que recebe quatro números ($a0-$a3) e calcula a média aritmética ($v0). addi $sp, $sp, -12 sw $t1, 8($sp) sw $t0, 4($sp) sw $s0, 0($sp) add $t0, $a0, $a1 add $t1, $a2, $a3 add $s0, $t0, $t1 srl $v0, $s0, 2 lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) add $sp, $sp, 12 jr $ra 31 Conjunto de instruções No caso de sub-rotinas que chamam outras sub-rotinas ou que são recursivas, é preciso tomar alguns cuidados adicionais: Salvar também o endereço de retorno ($ra) na pilha; Salvar o conteúdo dos registradores de passagem de parâmetros ($a0-$a3) na pilha antes de atualizá-los para a próxima chamada de sub-rotina. 32 Conjunto de instruções Alocação de memória MIPS: convenção de software, não uma parte da arquitetura MIPS. 33 Conjunto de instruções Formato das instruções de desvio Instruções de desvio condicional especificam dois registradores e um endereço alvo. De forma predominante, os desvios condicionais são para posições de memória relativamente próximas (para frente ou para trás). Representação: equivalente ao formato I. op rs rt endereço 6 bits 5 bits 5 bits 16 bits 34 Conjunto de instruções Formato das instruções de desvio Observações: O endereçamento é feito em relação ao PC. Na verdade, depende do valor de PC + 4 (endereço da próxima instrução). O endereço fornecido na instrução é interpretado como referente a uma palavra. Logo, o offset efetivo (em bytes) em relação a (PC + 4) contém 18 bits. Exercício: qual o tamanho da região endereçável? Para pensar: e se o branch condicional precisa alcançar uma posição mais longe? bne $s0, $s1, L2 J L1 beq $s0, $s1, L1 L2: 35 Conjunto de instruções Formato das instruções de desvio Instruções de desvio incondicional especificam diretamente o endereço alvo. Representação: formato J. op endereço 6 bits 26 bits Observações: O endereço fornecido na instrução é interpretado como referente a uma palavra. Logo, o endereço efetivo (em bytes) contém 28 bits. Como qualquer endereço deve ter 32 bits, os quatro bits que faltam são obtidos do próprio PC. Endereço: 4 bits mais significativos do PC 28 bits do endereço fornecido na instrução Exercício: qual o tamanho da região endereçável? 36 Conjunto de instruções O limite de 32 bits para uma instrução é interessante por manter a simplicidade de projeto. Mas, às vezes, seria interessante poder ter constantes e endereços maiores que aqueles delimitados pelos respectivos campos de cada instrução. Como criar uma constante/endereço de 32 bits? MIPS oferece a instrução lui (load upper immediate), a qual segue o formato I. Exemplo: lui $s0, 0x0061 Os 16 bits especificados na instrução como um imediato serão colocados nos 16 bits mais significativos do registrador $s0. Exercício: como podemos colocar o valor (em hexadecimal) 8fff 097b no registrador $t0? OBS: registrador $at – separado para o montador MIPS criar valores (constantes ou endereços) longos. 37 Conjunto de instruções Caracteres Representação clássica: código de 8 bits – ASCII (American Standard Code for Information Interchange) 38 Conjunto de instruções MIPS Oferece instruções para a movimentação de bytes. lb (load byte): carrega um byte da memória e o coloca nos 8 bits menos significativos de um registrador. OBS: Há a versão sem sinal desta instrução - lbu sb (store byte): copia o byte menos significativo de um registrador em um endereço de memória. UTF-16: 16 bits para representar os alfabetos de vários idiomas. MIPS também oferece instruções para a manipulação de conjuntos de 16 bits (half-words). lh (load half-word): carrega meia palavra da memória e a coloca nos 16 bits menos significativos de um registrador. OBS: Há a versão que não faz a extensão de sinal – lhu (mais utilizada). sh (store half-word): copia os 16 bits menos significativo de um registrador em um endereço de memória. 39 Conjunto de instruções Modos de endereçamento 40 Uma breve história da computação A necessidade de calcular com precisão e rapidez explica a adoção por parte dos humanos de dispositivos auxiliares, entre os quais podemos citar, inicialmente, o ábaco, utilizado por povos de diferentes partes do mundo. Num período um pouco mais recente, surgiram máquinas mecânicas de calcular, como aquelas propostas por Wilhelm Schickard (1592 – 1635) e Blaise Pascal (1623 – 1662). A máquina de Pascal (conhecida como Pascaline) foi efetivamente preservada. Essa máquina mecânica era capaz de realizar adições (inclusive com transporte) e subtrações (utilizando um sistema de complemento de 9). 41 Uma breve história da computação O grande Gottfried Leibniz (1646 – 1716) ampliou essas concepções ao introduzir um projeto mais intrincado capaz de, mecanicamente, realizar operações de multiplicação e divisão. Ele também é muito lembrado por seu pioneirismo no uso do sistema binário de numeração. Um salto nos leva até Charles Babbage (1791-1871), que concebeu o engenho diferencial (differential engine), um dispositivo mecânico capaz de construir tabelas de funções por meio do método das diferenças finitas. 42 Uma breve história da computação Sua concepção posterior de engenho analítico se aproximaria ainda mais do espírito das concepções do século XX, suscitando com mais clareza a noção de uma máquina de propósito geral controlada por um programa. Nesse contexto tecnológico dominado pela mecânica, a concepção moderna de Babbage, que envolvia o uso de algum tipo de memória para registro de instruções, beneficiou-se do uso, por parte de Joseph-Marie Jacquard (1752-1834) de cartões perfurados para guiar de maneira automatizada a operação de teares. Esta máquina seria dotada de uma unidade central de processamento capaz de escolher entre ações alternativas dependendo dos resultados de eventos anteriores (um recurso conhecido como branch condicional). 43 Uma breve história da computação Um passo tecnológico determinante foi a construção de circuitos eletrônicos, primeiramente baseados em válvulas (tubos de vácuo) e, posteriormente, em dispositivos semicondutores. Uma vantagem nítida dessa tecnologia com respeito ao uso de estruturas eletromecânicas diz respeito ao “fator tempo”, já que o chaveamento entre estados não envolve o movimento de partes mecânicas. Esforços pioneiros: ABC – Atanasoff-Berry Computer Colossus – concebida no âmbito do esforço de guerra britânico (Bletchley Park), com a participação de Alan Turing (1943). Possivelmente o primeiro dispositivo eletrônico a funcionar com algumas características que lembram as do computador – não era de propósito geral e não possuía um programa armazenado. 44 Uma breve história da computação ENIAC (Electronic Numerical Integrator And Computer): Concebido por J. Presper Eckert e John Mauchly, da Moore School of Electrical Engineering (University of Pennsylvania). Seu projeto foi completado em 1945. Tratava-se de um computador de “propósito geral” (programado pela conexão direta de fios – não havia programa armazenado), totalmente eletrônico e efetivamente operacional. Dispunha de um leitor de cartões perfurados e podia fornecer saídas nessa forma ou por meio de uma inspeção direta de lâmpadas que mostravam o conteúdo de registradores. Adotava representação decimal para os números manipulados. 45 Uma breve história da computação EDVAC (Electronic Discrete Variable Automatic Computer): Esse projeto é crucial para que se compreenda a estrutura de uma máquina moderna, pois, nele, a noção de programa armazenado se consolida. Percebe-se, ainda que de maneira não declarada, uma forte inspiração nas ideias de Turing. O documento “A First Draft of a Report on the EDVAC” serviu para a disseminação do que ficou chamado de arquitetura von Neumann. 46 Uma breve história da computação ACE (Automatic Computing Engine): Proposta de Alan M. Turing para a construção de um computador eletrônico. Turing ofereceu ricos detalhes relacionados ao projeto dos circuitos e à especificação das unidades de hardware, inclusive mostrando programas preliminares em código de máquina. O documento “Proposal for Development in the Mathematics Division of an Automatic Computing Engine (ACE)”, republicado em 1946, representa a primeira especificação quase completa de um computador eletrônico digital de propósito geral com programa armazenado. Interessante: o projeto de Turing mostrava características bastante semelhantes às arquiteturas RISC. 47 Uma breve história da computação Baby (Manchester): Primeiro computador digital de propósito geral com programa armazenado a efetivamente funcionar (21 de Junho de 1948). Construído no Royal Society Computing Machine Laboratory na Universidade de Manchester, pelos engenheiros F.C. Williams e Tom Kilburn. O primeiro programa, armazenado em um tubo de raios catódicos, possuía apenas dezessete instruções. 48 Exemplos Problema: computar o quociente e o resto referentes à divisão inteira entre dois números contidos nos registradores $a0 e $a1, respectivamente. 49 Créditos Figuras extraídas de D. A. Patterson e J. L. Hennessy, “Computer Organization and Design: The Hardware/Software Interface”, Morgan Kauffman, 5ª edição, 2013. http://textbooks.elsevier.com/web/product_details.aspx?isbn=9780124077263 50