Capítulo 5 − Nível ISA − Primeiro nível desenvolvido, historicamente − Atualmente existente entre o nível da microarquitetura e do sistema operacional − Compatibilidade com os níveis ISA anteriores !! => Pressão do mercado − Características de um bom nível ISA: − Deve definir um conjunto de instruções que possam ser implementadas eficientemente na tecnologia atual e futura. − Deve fornecer um alvo fácil para o código compilado: regularidade e uma faixa de escolhas completas. − Satisfação do projetista de hardware e do projetista de software. 5.1 Visão geral do nível ISA 5.5.1 Propriedades do nível ISA − Nível ISA pode ser entendido como sendo a aparência do computador para um programador em linguagem máquina =>é a saída do compilador. − Nível ISA =>parte visível e necessária ao compilador − Tipo do modelo de memória; − Tipos de registradores existentes − Tipos de dados − Instruções disponíveis e registradores envolvidos − Algumas arquiteturas possuem o nível ISA especificado formalmente : SPARC e JVM. − Dois modos de operação: − Modo Kernel: Utilizado para rodar sistemas operacionais => permite que todas as instruções sejam executadas. − Modo usuário: Utilizado para rodar aplicativos e não permite a execução de certas instruções (acesso a cache). 5.1.2 Modelos de memória 98 − Todos os computadores dividem a memória em células que possuem endereços consecutivos (células de 1 a 60 bits) => 8 bits é o mais comum (1 byte). − bytes geralmente organizados em grupos de palavras de 4 (32 bits) ou 8 (64 bits) bytes. − Palavras alinhadas ou não: − Palavras alinhadas: Pentium II => busca de 8 bytes de uma única vez => três últimos bits de endereçamento sempre iguais a "000". − Poucas máquinas possuem um espaço de endereçamento distinto para dados e instruções − Possibilidade de endereçar 232 bytes de programas e 232 bytes de dados usando apenas 32 linhas de endereçamento. − Uma operação de escrita não irá sobrescrever a área de programa. − Comportamento da memória: − Um LOAD após um STORE na mesma referência de memória pode não retornar o valor previamente armazenado !! => reorganização das microinstruções (estrutura superescalar); sistema multiprocessado com memória comum. 5.1.3 Registradores − Todos os computadores possuem alguns registradores visíveis ao nível ISA. − Registradores de uso geral: Utilizados para armazenar variáveis locais e resultados intermediários. Possibilitam o acesso rápido a dados muito utilizados. − Idênticos e intercambiáveis (em algumas máquinas). − Máquinas RISC => grande quantidade de registradores de uso geral (CPU muito mais rápida do que a memória). − Registradores de uso específico: Program Counter, Stack pointer,... − Registrador de flags ou PSW (Program Status Word): Armazena vários bits distintos necessários a CPU. − Códigos de condição: refletem o resultado da última operação executada: 99 N (negativo), Z (zero), V (overflow), C (carry), A (carry auxiliar), P (paridade − geralmente quando o resultado possui uma paridade par) − Outros bits: modo da CPU (kernel ou usuário), Trap (ou Trace, utilizado para debugar), nível de prioridade da CPU, interrupção,... 5.1.4 Instruções − Principal característica do nível ISA: conjunto de instruções da máquina => controlam o que a máquina pode fazer. − Instruções de LOAD, STORE e MOVE; − Instruções aritméticas e booleanas; − Instruções de comparação e salto. 5.1.5 Visão geral do nível ISA do Pentium II − Desenvolvido a partir de várias gerações. − Execução do código gerado para o 8086 e 8088. − 8086 e 8088: processadores de 16 bits (8088 possui um barramento de dados de 8 bits). − 80286: CPU de 16 bits. Possui um grande espaço de endereçamento pouco utilizado pelos programas por utilizar a mesma segmentação de memória do 8086, ao invés de utilizar uma memória linear de 224 bytes. − 80386: primeira máquina da Intel de 32 bits − IA−32 . − Principais avanços a partir do 80386: Introdução de instruções MMX − Pentium II: − Três modos de operação: Dois para utilizá−lo com o 8088. − Modo Real: Todas as características adicionadas a partir do 8088 são desligadas e o Pentium II operara como um simples 8088. Se o programa fizer algo errado toda a máquina para. − Modo 8086 Virtual: Possibilita a execução de programas compilados para o 8088 de maneira protegida. Neste modo um sistema operacional está no controle de toda a máquina. Se o programa fizer algo errado o sistema operacional é notificado, ao invés de toda a máquina parar (exemplo: janela do MS−DOS aberta no Windows). − Modo Protegido: o Pentium II opera como um Pentium II. Quatro níveis de privilégio estão disponíveis e controlados por bits na PSW. − Nível 0: Corresponde ao modo Kernel em outras máquinas e possui acesso total à màquina. Utilizado pelo sistema operacional. − Nível 3: Utilizado por aplicativos do usuário. Bloqueia o acesso a certas instruções críticas e a alguns registradores de controle. − Níveis 1 e 2: raramente utilizados. − Possui um grande espaço de endereçamento: Divisão da memória em 16.384 segmentos, cada um indo do endereço 0 ao endereço 232 => a maioria dos sistemas operacionais (Incluindo UNIX e Windows) utilizam apenas um 100 segmento => os programas "enxergam" um endereçamento linear de 232 bytes. Palavras de 32 bits armazenadas no formato little endian (bytes mais baixos nos endereços mais baixos). − Registradores: 5.1.6 Visão Geral do Nível ISA do UltraSPARC II 101 − Arquitetura SPARC introduzida em 1987 pela SUN (máquina de 32 bits) => RISC − UltraSPCARC II: 64 bits, baseada na versão 9 da arquitetura. − Memória linear de 264 bytes => nenhuma máquina realmente implementa o total da memória => armazenamento defaul é big endian, podendo ser alterado por um bit na PSW. − Dois grupos de registradores: − 32 registradores de ponto flutuante − Armazenam valores de 32 bits (precisão simples) ou 64 bits (precisão dupla). − Podem ser combinados para armazenar valores de 128 bits (precisão quadrupla). − 32 registradores de uso geral de 64 bits: chamados de R0 a R31 − Gx: constantes, variáveis e ponteiros necessários em todos os procedimentos. − Ix e Ox: passagem de parâmetros para procedimentos. − FP: aponta para a base do quadro atual, utilizado para acessar variáveis locais (tal como o LV). − SP: Indica o topo da pilha. − R31: Utilizado para chamadas de procedimentos parar armazenar o endereço de retorno. − O UltraSPARC II possui mais do que 32 registradores de uso geral, entretanto apenas 32 são visíveis ao programa a qualquer instante de tempo => Janela de Registradores − simulação de uma pilha, usando registradores. − Existem vários conjuntos de registradores, tal como existem vários quadros na pilha. − Exatamente 32 registradores estão visíveis a qualquer instantes − CWP (Current Windows Pointer) possui a informação de qual conjunto de registradores está atualmente em uso. 102 − A chamada de um procedimento esconde o conjunto antigo de registradores e fornece um novo conjunto decrementando CWP. − Arquitetura locad/store: As únicas operações que podem acessar a memória diretamente são LOADs e STOREs. − Todos os operandos de instruções lógicas e aritméticas devem vir de registradores ou fornecidos pela instrução. Os resultados são armazenados em registradores (não na memória). 5.1.7 Visão geral da JVM 103 − Nível ISA não comum. − Modelo de memória idêntico ao IJVM mas com o acréscimo de mais uma região => ordenamento em big endian. − Quadro de variáveis locais − Pilha de operandos − Área de método − Área de constantes − Heap => utilizada para armazenar objetos muito grandes ou dinâmicos. − Não possui registradores de uso geral que podem ser carregados ou descarregados por controle do programa => máquina puramente de pilha. 5.2 Tipos de Dados 5.2.1 Dados numéricos − Números inteiros: 8, 16, 32 e 64 bits − Maioria dos computadores atuais armazenam números inteiros em complemento de dois. − A maioria dos sistemas suporta números com sinal (signed) e sem sinal (unsigned). − Ponto−Flutuante: 32, 64 ou 128 bits − A maioria dos computadores possuem instruções específicas para trabalhar com pontos flutuantes bem como registradores específicos para números em ponto−flutuante. 5.2.2 Dados não numéricos − Processamento de texto ou base de dados − Caractere: ASCII (7 bits) ou UNICODE (16 bits) − String: seqüência de caracteres. Geralmente limitada por um caractere especial. − Booleano: um único bit pode representar uma variável booleana (na teoria). Na prática utiliza−se um byte ou uma palavra. − Ponteiro: armazena um endereço. 5.2.3 Tipos de dados no Pentium II − Números inteiros com sinal em complemento de dois, − Números inteiros sem sinal, − Inteiros com 8 ou 16 bits − Números BCD − Números em ponto−flutuante (IEEE 754) − Os operandos não precisam ser alinhados => alinhamento melhora a performance. − Possui instruções específicas para lidar com caracteres em ASCII 104 5.2.4 Tipos de Dados do UltraSPARC II − Inteiros com sinal (complemento de dois) ou sem − Ponto−flutuante com 32, 64 ou 128 bits (IEEE 754) − Não suporta BCD − Todos os operandos devem estar alinhados na memória. − Caracteres ou Strings não são suportados por instruções específicas. 5.2.5 Tipos de Dados no JVM − Cada operando possui um tipo específico e um tamanho conhecido da compilação. − Inteiros com sinal em complemento de dois − Não possui números inteiros sem sinal − Não possui números em BCD − Suporta caracteres: UNICODE (16 bits) − Programas do usuário não podem acessar diretamente ponteiros 5.3 Formatos de Instruções − Instrução: OPCODE + informação adicional; origem dos operandos ou destino do resultado. − Origem/destino dos operandos: Endereçamento 105 − As instruções podem ou não ter o mesmo tamanho e não possuem uma relação direta com o tamanho da palavra da CPU. − Instruções de mesmo tamanho: facilidade de implementação e decodificação => geralmente desperdiçam espaço. 5.3.1 Critérios de projeto para formatos de instruções − Formato das instruções: − Um dos principais parâmetros no projeto de uma nova CPU. − A escolha de uma determinada característica depende da tecnologia atual => sobrevivência depende da capacidade de predição da tecnologia futura. − Instruções curtas são melhores do que instruções longas. − Instruções curtas podem ser mais difíceis de serem decodificadas e executadas − Critérios: − Tamanho da instrução − Espaço suficiente no formato para conter todas as operações desejadas (OPCODE) => espaço livre para aumentar a quantidade de operações no futuro. − Número de bits utilizados no campo de endereçamento. Compromisso entre números de bits e resolução da memória. 5.3.2 Expandindo OPCodes − Supondo uma máquina com instruções de 16 bits: − 16 possíveis instruções com 3 endereços: 106 − Supondo que esta mesma máquina precise ter: − 15 instruções de três endereços; − 14 instruções de dois endereços; − 31 instruções de um endereço; − 16 instruções sem endereçamento 5.3.3 Formatos de instrução do Pentium II − Formatos complexos e irregulares com até seis campos de tamanho variável, cinco opcionais => compatibilidade com processadores anteriores. 107 − Instruções de dois operandos: Se um estiver na memória o outro deve estar em um registrador. 5.3.4 Formatos de instrução do UltraSPARC II − Instruções de 32 bits, alinhadas na memória − Instruções simples especificando uma única ação − Número limitado de formatos de instrução (até a data de edição do livro eram um total de 31 formatos). − Dois primeiros bits: ajudam na determinação do formato da instrução e indicam a posição do resto do opcode. 5.3.5 Formatos de instruções do JVM − Formato simples − Todas as instruções utilizam um OPCODE de 1 byte. 108 109 5.4 Endereçamento − Grande parte dos bits em um programa são utilizados para especificar a origem/destino dos operandos/resultados. − Redução da quantidade de bits necessárias para especificar operandos: − Utilização de registradores x memória − Operandos implícitos − Três endereços, Dois endereços, um endereço, nenhum endereço 5.4.1 Modos de Endereçamento − Endereçamento completo: Necessidade de muitos bits e do conhecimento do endereço na etapa de compilação. 5.4.2 Endereçamento imediato − A instrução contém o dado e não o endereço do dado => Operando imediato. − Não necessita de memória extra para buscar o operando. − Funciona somente com constantes. MOV AL, 4 5.4.3 Endereçamento direto − A instrução contém o endereço (memória) de um operando. − O conteúdo da memória pode ser alterado, mas não o endereço. − Funciona bem com variáveis globais. MOV AL, [0004] 5.4.4 Endereçamento por registrador − Similar ao endereçamento direto, mas utiliza um registrador ao invés de uma posição de memória. − Muito útil quando necessita−se diversas vezes da mesma variável MOV AL,BH 5.4.5 Endereçamento indireto por registrador − O endereço de uma variável é armazenado em um registrador. − Registrador funciona como um ponteiro. MOV AL,[BX] 5.4.6 Endereçamento indexado 110 − A palavra da memória é referenciada como um offset a partir de um registrador. − Endereço fornecido por um registrador+offset MOV AL,[BX+0020] 5.4.7 Endereçamento indexado por base − A palavra da memória é referenciada pela soma de dois registradores. − Endereço fornecido por registrador_base+registrador(+offset) MOV AL,[SI+BX+0005] 5.4.8 Endereçamento por pilha − Possibilidade de não haver nenhum endereçamento na instrução − Argumentos obtidos diretamente da pilha de operandos. − Notação infix x RPN (Reverse Polish Notation) − Notação RPN => ideal para computadores com pilha de operandos. Ex. : (8 + 2 x 5)/(1 + 3 x 2 − 4) => 8 2 5 x + 1 3 2 x + 4 − / 5.4.9 Modos de endereçamentos para instruções de salto 111 − Necessidade de fornecer o endereço para o alvo do salto. − Endereçamento direto => endereço fornecido na própria instrução. − Endereçamento por registrador => flexibilidade e fonte de erros. − Endereçamento indexado => flexibilidade e fonte de erros. − Endereçamento relativo => fornece um offset (positivo ou negativo) utilizando como base o valor atual de PC. 5.4.10 Ortogonalidade de OPCODES e Modos de Endereçamento 5.4.11 Modos de Endereçamento do Pentium II − Suporta os modos: Imediato, direto, por registrador, indireto por registrador, indexado e um modo especial para elementos em vetores. − Utiliza o campo MODE (MOD+REG+R/M) para controlar os modos de endereçamento. − Em alguns modos utiliza o byte e SIB (Scale, Index, Base) Endereço = Index_register x Escala + Base_register onde Escala = 1, 2, 4 ou 8. Dependendo de Scale. 112 5.4.12 Modos de Endereçamento do UltraSPARC II − Máquina de três endereços − Todas instruções utilizam endereçamento imediato ou por registrador (exceto as de acesso a memória) − Endereçamento por registrador: 5 bits indicando o registrador − Endereçamento imediato: 13 bits indicando a constante (com sinal) − Instrução de LOAD/STORE − 1º Modo: Endereço dado pela soma de dois registradores − 2º Modo: Endereçamento indexado usando um offset de 13 bits (com sinal) 5.4.13 Modos de Endereçamento do JVM − Cada instrução possui um modo de endereçamento associado a ela − Utiliza principalmente o modo indexado. − Poucas instruções utilizam endereçamento imediato − Os modos de endereçamento por registrador e indireto por registrador não são suportados. 113 5.4.14 Discussão sobre modos de Endereçamento 5.5 Tipos de Instruções 5.5.1 Instruções para movimentação de dados − Mover possui o significado de "copiar" − LOAD, STORE, MOVE − As instruções devem fornecer a quantidade de palavras a serem movidas − Alguns conjuntos ISA fornecem instruções para mover menos do que uma palavra. 5.5.2 Operações de dois argumentos − Combinam dois operandos para produzir um resultado − Instruções aritméticas (adição, subtração, multiplicação, divisão): Números inteiros e/ou ponto flutuante. − Instruções booleanas (AND, OR, XOR, NOR, NAND) => muito utilizadas também para mascaramento. 5.5.3 Operações com um argumento − Deslocamento : com sinal ou sem sinal (aritmético ou lógico) − Rotação − booleana: NOT − Aritméticas: INC, NEG (0 − x => aditivo inverso) 5.5.4 Comparações e Saltos Condicionais 114 − A maioria das CPUS fornecem flags indicando o resultado da última instrução executada: C, P, Z, N, O, A − Comparação de dois números: − Número com sinal ou sem sinal − Máquinas com formato de instrução de três endereços: dois endereços para os argumentos e o terceiro indicando a posição do salto. − Máquinas com formato de instrução de dois endereços: Duas instruções para executar o salto condicional: Primeira para efetuar a comparação e a segunda para efetuar o salto. 5.5.5 Instruções de chamada de Procedimento − Procedimento: grupo de instruções que executam determinada tarefa e que pode ser chamado de diversas posições no programa. − Quando o procedimento termina sua tarefa ele deve retornar para a primeira instrução após a chamada => endereço de retorno deve ser salvo ou fornecido ao procedimento. − Possibilidade de recursão => armazenamento do endereço de retorno na pilha 5.5.6 Controle de Laços (Loops) − Geralmente utiliza−se um registrador previamente especificado para ser o contador que pode se incrementado/decrementado e testado. − Teste no fim − Teste no começo 5.5.7 Entrada/Saída − I/O Mapeado em memória: Instruções de LOAD/STORE − I/O separado da memória: Instruções de IN/OUT. 1 − Pooling: I/O programável com espera: O hardware avisa em um registrador quando existe dados disponível. 2 − I/O por interrupção: O hardware solicita uma interrupção quando existe dado disponível. 3 − I/O por DMA: O hardware avisa que já existem novos dados que já foram transferidos para a memória 115 5.5.8 Instruções do Pentium II 116 5.5.9 Instruções do UltraSPARC II 117 5.5.10 Instruções do JVM − 226 Instruções 118 5.5.11 Comparação entre conjuntos de Instruções − Pentium II − Máquina CISC de 32 bits de dois endereços − Modos de endereçamento peculiares e irregulares − Várias instruções para acessar a memória −UltraSPARC II − Máquina RISC de 64 bits de três endereços − Arquitetura LOAD/STORE − Poucos modos de endereçamento − Conjunto de instruções compacto e eficiente − JVM − Máquina de pilha (stack) − Praticamente sem modos de endereçamento − Conjunto de instrução muito regular e de densa codificação 5.6 Fluxo de controle − Seqüência na qual as instruções são executadas dinamicamente => Execução do programa. 5.6.1 Fluxo Seqüencial de controle e Saltos 119 5.6.2 Procedimentos − Principal técnica utilizada em programas estruturados − Um procedimento altera o fluxo do programa => Ao final do procedimento o programa volta ao ponto da chamada ou na instrução após a chamada. − Procedimentos recursivos => procedimento capaz de chamar ele mesmo. 120 5.6.3 Co−Rotinas − Utilizado para simular processos paralelos em uma única CPU. − Não utiliza instruções como CALL e RETURN. 5.6.4 Traps − Tipo de procedimento => iniciado automaticamente devido a alguma condição causada pelo programa => condição rara mais importante (Ex. Overflow, violação de proteção, opcode indefinido, divisão por zero, etc.) − Trap Handler. 121 5.6.5 Interrupções − Fluxo de controle alterado por outro dispositivo => I/O − Processador pára o programa atual e passa a executar o programa associado ao nível da interrupção solicitada => ao final do programa da interrupção o processador volta a executar o programa anterior =>transparência. − Prioridades de interrupção 122