Baixe o app para aproveitar ainda mais
Prévia do material em texto
Capítulo 4 − Nível da microarquitetura − Nível acima da lógica digital − Função: Implementar a ISA (Instruction Set Architecture) − O projeto da microarquitetura depende diretamente da ISA, além dos objetivos de custo e performance 4.1 Exemplo de Microarquitetura − Cada microarquitetura é única => não existe fórmula − Exemplo: Subconjunto da JVM => Apenas instruções com inteiros (IJVM) − Microprograma (ROM): Busca, decodificação e execução das instruções IJVM − Cada instrução IJVM é uma função a ser chamada pelo programa principal − Programa principal: Loop simples, sem fim => determina a próxima função chamada, executa a função, determina a próxima função, executa a função,... − Instruções IJVM: curtas, normalmente um ou dois campos. O primeiro campo é sempre o OPCODE. − Microprograma: possui um conjunto de variáveis, acessadas por todas as funções => estado do computador MAR (Memory Address Register): Porta de endereçamento de memória (32 bits) MDR (Memory Data Register): Porta de dados de memória (32 bits), leitura ou escrita na memória. PC (Program Counter): indica a posição de memória(endereço) que contém a próxima instrução a ser executada. MBR (Memory Byte Register) : Porta de dados da memória (8 bits), apenas leitura da memória SP (Stack Pointer): Aponta para o topo da pilha LV (Local Variable): Aponta para a base das variáveis locais dentro da pilha CPP (Constant Pool Pointer): Aponta para a base da área de constantes. TOS OPC H (Holding Register) 79 4.1.1 Data Path − Possui a ULA, suas entradas e saídas. − Conjunto de registradores de 32 bits (arquivo de registradores) => acessíveis apenas no nível da microarquitetura (pelo microprograma) − 6 linhas de seleção da função da ULA => apenas 16 funções úteis − Número negativo: Complemento de dois − Argumentos da ULA: − 1º argumento: sempre do registrador H (Holding) − 2º argumento: Qualquer um dos outros registradores, excluindo o H e MAR 80 − Saída da ULA: Alimenta o deslocador − Deslocador: − SLL8 (Shift Left Logical) − SRA1 (Shift Right Arithmetic) − É possível ler e escrever em um mesmo registrador no mesmo ciclo de relógio. Temporização da via de dados Subciclos: − liberação dos sinais de controle − leitura dos registradores − operação da ULA e deslocador − propagação do resultado para os deslocadores − Temporização rígida; − Ciclo de relógio suficientemente grande − Menor tempo possível de propagação na ULA (e deslocador) − Carregamento rápido dos registradores 81 Operação de Memória − Duas comunicações com a memória − porta de acesso de memória de uma palavra, 32 bits => Controlada por MAR e MDR. − porta de acesso de memória de um byte, 8 bits = > Controlada por MBR e PC. − MAR contém endereços de palavras − PC contém endereços de bytes − MAR/MDR => Utilizados para ler palavras de dados no nível ISA => 32 bits − PC/MBR => Utilizados para ler o programa executável no nível ISA => 8 bits − Memória física orientada por Bytes (total de 4GB) => mapeamento de MAR no barramento de endereço. − Leitura de MBR no barramento B: − Com sinal − Sem sinal 4.1.2 Microinstruções − 29 sinais para controlar a via de dados: − 9 sinais para escrita nos registradores − 9 sinais para leitura dos registradores − 8 sinais para controlar a ULA e deslocador − 2 sinais para indicar leitura ou escrita via MAR/MDR − 1 sinal para indicar busca de instrução via PC/MBR − Os sinais especificam a operação da via de dados em um ciclo de relógio. − Uma leitura da memória (em MDR ou MBR) iniciada ao fim do ciclo k só terá o dado disponibilizado a partir do ciclo k+2. − É possível ler dados distintos da memória em dois ciclos consecutivos. − Não é possível ler mais de um registrador ao mesmo tempo => decodificação da leitura => necessidade de apenas 24 bits para controlar a via de dados. 82 − Os 24 bits controlam a via de dados em um ciclo da via de dados => necessidade de informar o que será feito no próximo ciclo => inclusão dos campos NEXT_ADDRESS e JAM. ADDR: Contém o endereço da possível próxima microinstrução JAM: Determina como a próxima microinstrução é selecionada ALU: Funções da ULA e Deslocador C: Seleção de qual registrador é carregado do barramento C MEM: Funções da memória B: Seleção de qual registrador é lido no barramento B 4.1.3 Controle das Microinstruções: MIC−1 − Seqüenciador: Determina quais sinais de controle devem ser habilitados em cada ciclo, responsável por seguir uma seqüência de operações necessárias para a execução de uma única instrução ISA: 1. Determina o estado de cada sinal de controle do sistema 2. Explicita o endereço da próxima microinstrução a ser executada − Control Store: memória que contém todo o microprograma (512 palavras de 36 bits). − As microinstruções NÃO são armazenadas seqüencialmente na memória de controle => cada microinstrução especifica sua sucessora. − MPC (MicroProgram Counter): Especifica o endereço da memória de controle − MIR (MicroInstruction Register): Saída de dados da memória de controle 83 − MIR é carregado na transição negativa do clock com o dado apontado por MPC. 84 − JMPC = 0 −Bit de mais alta ordem de MPC = (JAMZ AND Z) OR (JAMN AND N) OR NEXT_ADDRESS(8). − Duas possíveis sucessoras para a microinstrução corrente: − JMPC = 1 − MPC = MBR OR NEXT_ADDRESS − Normalmente os 8 bits de mais baixa ordem de NEXT_ADDRESS são zero. O bit de mais alta ordem pode ser "1" ou "0". 4.2 Exemplo de ISA: IJVM 4.2.1 Pilhas (Stacks) − Local de memória utilizada para variáveis temporárias (locais). − Acessada por dois registradores: − LV − Local Variables − aponta para a base das variáveis locais − SP − Stack Pointer − aponta para o topo da pilha − Quadro local: estrutura de dados entre LV e SP 85 − Pilha de operandos: Quando a pilha é utilizada para armazenar valores intermediários em uma expressão. Nem todas as máquinas utilizam este recurso. 4.2.2 Modelo de Memória da IJVM − Memória vista de duas formas: − Vetor de 4G bytes − Vetor de 1G palavras, cada palavra 4 bytes − Endereços implícitos que fornecem a base para um ponteiro => as instruções só podem acessar a memória indexando a partir destes ponteiros. − Separação da memória em quatro partes, acessíveis a qualquer momento: 1. Área de constantes (Constant Pool): − Não pode ser escrita por um programa . − Carregada quando o programa é lido para a memória. − Consiste de constantes, strings e ponteiros para outras áreas de memória. − CPP: Aponta sempre para a base desta área (endereço da primeira palavra da área de constantes). 2. Quadro de variáveis Locais (Local Variable Frame): − Não inclui a pilha de operandos − Utilizada para a alocação de variáveis durante a execução de um procedimento. − A pilha de operandos está localizada exatamente acima do quadro de variáveis locais. − Argumentos da chamada do procedimento armazenados no começo do quadro de variáveis locais. − LV: Possui o endereço da primeira posição do quadro de variáveis locais. 3. Pilha de Operandos: − A pilha não excede um certo tamanho, garantido pelo compilador Java. − A área da pilha de operandos é alocada acima da área de variáveis locais − SP: aponta para o topo da pilha de operandos => valor alterado durante a execução do programa. 4. Área de Métodos: − Região de memória que contém o programa. 86 − Tratada como um vetor de bytes. − PC: Aponta para a próxima instrução a ser buscada. − CPP, LV e SP => Ponteiros para palavras (4 bytes), todos offsets utilizados para indexar estas áreas de memória são offsets de palavras => LV+1 não representa a posição de memória do byte acima de LV mas a posição de memória do quinto byte acima de LV. − PC => Ponteiro para byte 87 4.2.3 Conjunto de instruções IJVM − Cada instrução consiste de um OPCODE e, em alguns casos,de um operando (offset de memória ou constante) − byte, const e varnum: um byte − disp, index e offset: dois bytes − Fontes das palavras a serem colocadas na pilha: − Área de constantes: LDC_W − Quadro de variáveis locais: ILOAD − Área de instruções: BIPUSH − Local de armazenamento das variáveis retiradas da pilha: − Quadro de variáveis locais: ISTORE − Própria pilha: IADD, ISUB, IAND, IOR − Saltos: − Incondicional: GOTO − Condicional: IFEQ, IFLT, IF_ICMPEQ − Chamada de função (método): INVOKEVIRTUAL − Retorna de função : IRETURN 88 Execução de um método 1. A função que chama o método coloca um apontador (OBJREF) para o objeto a ser chamado na pilha; 2. A função que chama o método coloca os parâmetros do método na pilha (Parâmetro 1, Parâmetro 2, Parâmetro 3). 3. Finalmente executa−se o INVOKEVIRTUAL 4. A instrução INVOKEVIRTUAL possui um deslocamento (disp), como argumento => indica a posição na área de constante que possui o endereço inicial na área de métodos. − Primeiros 4 bytes na área de método: 2 bytes indicando o número de parâmetros (OBJREF é contado como o Parâmetro 0) => Juntamente com SP fornece a posição de OBJREF. LV apontará para OBJREF. 2 bytes indicando o tamanho da área de variáveis locais do método que será executado => necessário para determinar a nova posição de SP. − Quinto byte é a primeira instrução a ser executada. 5. Os dois primeiros bytes da área de métodos são utilizados para posicionar LV => OBJREF é substituído por um ponteiro indicando a posição do antigo PC. 6. Acima do antigo valor de PC, o antigo valor de LV também é armazenado. 7. SP passa a apontar para o endereço da posição do antigo LV (pilha encontra− se vazia). 8. PC passa a apontar para o quinto byte da área de métodos. 89 90 Retorno de um método A instrução IRETURN reverte as operação da instrução INVOKEVIRTUAL − Desaloca o espaço utilizado pelo método que estava sendo executado. − Retorna a pilha para o estado anterior: − OBJREF e todos os parâmetros são retirados da pilha − O valor de retorno é colocado no topo da pilha, na posição inicialmente ocupada por OBJREF. 91 4.2.4 Compilando Java para IJVM 92 4.3 Exemplo de Implementação 4.3.1 Microintruções e Notação − Memória do microprograma: 36 bits por palavra − Controle a cada ciclo: − Possibilita executar diversas operações concorrentemente − Necessário para compreender e verificar as operações − Mais fácil para uma possível otimização (redução de ciclos por instrução) − Notação: MAL (Micro Assembly Language) SP = SP+1; rd => incrementa SP e inicia uma operação de leitura da memória MDR = SP => copia o valor de SP para MDR MD = H + SP => adiciona o conteúdo do registrador H ao registrador SP escrevendo o resultado em MDR. MDR = SP + MDR => INVÁLIDO ! (um dos argumentos tem que ser H) H = H − MDR => INVÁLIDO ! (o subtraendo deve vir de H) SP = SP+1;rw => Incrementa SP e inicia uma operação de escrita na memória (4 bytes) SP = SP+1; fetch => incremeta SP e inicia uma operação de busca de instrução (1 byte) goto label => salto incondicional para a próxima microinstrução marcada por "label" Z = TOS => Utilizada para verificar se o valor de um registrador é nulo. Simplesmente passa o registrador pela ULA, sem armazenar o resultado. N = TOS => Similar a anterior, porém testa se o valor do registrador é negativo. if (Z) goto L1; else goto L2 => Salto condicional Z=TOS; if (Z) goto L1; else goto L2 goto (MBR or value) => goto (MBR) => utiliza o bit JMPC 93 − Nem todas as operações são permitidas − O mesmo registrador não pode receber um valor da memória e da via de dados no mesmo ciclo: MAR = SP;rd MDR = H − Cada microinstrução fornece o endereço para a próxima microinstrução 94 4.3.2 Implementação do IJVM usando o MIC−1 − 112 microinstruções − As microinstruções não estão necessariamente em posições subsequentes − TOS: contém o valor da memória apontada por SP − Topo da pilha − OPC: registrador temporário. Pode ser utilizado para armazenar o valor de PC em uma instrução de salto. − A seqüência de microinstruções sempre começa no endereço igual ao OPCODE do IJVM. − BIPUSH: Coloca um byte na pilha − ILOAD: −WIDE: Altera o índice das instruções ILOAD e ISTORE −IINC: Soma uma constante a uma variável local 95 96 97 98
Compartilhar