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 2 32 bytes de programas e 2 32 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 2 24 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 2 32 => a maioria dos sistemas operacionais (Incluindo UNIX e Windows) utilizam apenas um 100
segmento => os programas "enxergam" um endereçamento linear de 2 32 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 2 64 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