Intruções de Máquina INSTRUÇÃO DE MÁQUINA Quem executa um programa é o hardware e o que ele espera encontrar é um programa em linguagem de máquina (uma sequência de instruções de máquina em código binário). Um programa em linguagem de alto nível não pode ser executado diretamente pelo hardware. Ele tem que ser transformado (traduzido) para linguagem de máquina por um compilador, antes de ser carregada em memória, para que o hardware possa executá-lo. A linguagem de máquina é composta de códigos binários, representando instruções, endereços e dados e está totalmente vinculada ao conjunto ("set") de instruções da máquina. Funcionalmente as operações do computador são: matemáticas (aritméticas, lógicas, de complemento, de deslocamento...) movimentação de dados (memória <--> registrador) entrada-saída (leitura e escrita em dispositivos externos dispositivos de Entrada / Saída) controle (desvio da sequência de execução, parar, etc...) Obs.: O conjunto de instruções de alguns processadores, como por exemplo o Intel 8080, não possui instruções para multiplicação ou divisão; portanto, um programa em linguagem de máquina, nestes processadores, não pode fazer multiplicação ou divisão diretamente (somente através de combinação de outras instruções). Já um programa em linguagem de nível mais alto pode implementar comandos de multiplicação (ou divisão) que combinem uma série de instruções binárias do conjunto de instruções para fazer uma multiplicação (ou divisão) através de repetidas somas (subtrações) ou por deslocamento de bits. Ex. de um conjunto de instruções de uma máquina hipotética: Instrução Significado Carregar no Load acumulador Salvar na Store memória Add Sub Mult Div Jmp Jz Jnz Read Print Stop Operação Código ACC <-- op 0000 op <-- ACC 0001 ACC <-- ACC + op ACC <-- ACC Subtrair op ACC <-- ACC * Multiplicar op ACC <-- ACC / Dividir op Desviar CI <-- op Desviar, se ACC CI <-- op, se igual zero ACC = 0 Desviar, se ACC CI <-- op, se não zero ACC != 0 Ler entrada op <-- entrada Imprimir saida <-- op Terminar Somar 0010 0011 0100 0101 0110 0111 1000 1001 1010 1100 Cada uma das instruções tem um código binário associado, que é o código da operação. Serão usadas as seguintes convenções: Operador Significado Operador Significado + * / adição subtração multiplicação divisão ~ = != | <-- atribuição ^ << >> deslocamento à & esquerda deslocamento à direita not (negação) igual diferente or (AND) exclusive or (XOR) and (E) FORMATO DAS INSTRUÇÕES Código de operação (OPCODE) Operando 1 (OP1) OP OP 2 3... Código de Operação ou OPCODE - identifica a operação a ser realizada pelo processador. É o campo da instrução cuja valor binário identifica (é o código binário) da operação a ser realizada. Este código é a entrada no decodificador de instruções na unidade de controle. Cada instrução deverá ter um código único que a identifique. Operando(s) - é o campo da instrução cujo valor binário sinaliza a localização do dado (ou é o próprio dado) que será manipulado (processado) pela instrução durante a operação. Em geral, um operando identifica o endereço de memória onde está contido o dado que será manipulado, ou pode conter o endereço onde o resultado da operação será armazenado. Finalmente, um operando pode também indicar um Registrador (que conterá o dado propriamente dito ou um endereço de memória onde está armazenado o dado). Os operandos fornecem os dados da instrução. Obs: Existem instruções que não tem operando. Ex.: Instrução HALT (PARE). Há diversos formatos de instruções, com características particulares, vantagens e desvantagens. O conjunto de instruções de uma máquina pode ser constituído por instruções de diversos formatos. Esta flexibilidade permite a escolha da instrução adequada para aplicação em cada caso. Conjunto de instruções pode ser analisado sob alguns aspectos, por exemplo: - quantidade de instruções - quantidade de operandos - modo de endereçamento (é a forma de sinalizar a localização de um dado - endereçamento imediato, direto, indireto, indexado). Exemplos: ADD OP1 OP2 => ADD OP1 OP2 => OP3 ADD OP1 => Soma conteúdo de OP1 e (OP1) <-OP2 e armazena o resultado (OP1) + (OP2) em OP1 Soma conteúdo de OP1 e (OP3) <-OP2 e armazena o resultado (OP1) + (OP2) em OP3 Soma conteúdo de OP1 e (ACC)<--(ACC) ACC e armazena o resultado + (OP1) em ACC LTR - Linguagem de Transferência entre Registradores (register transfer language) A LTR é utilizada para sinalizar o processamento de uma operação, mostrando o que acontece com os registradores e posições de memória como resultado do processamento de uma instrução. caracteres alfanuméricos significam abreviaturas de nomes de registradores ou posições de memória (ex: REM. MP) parênteses indicam conteúdo, no caso de registradores, ou o valor é um endereço na MP. seta indica atribuição (transferência de conteúdo entre registradores ou entre registrador e memória principal) · Ex.: REM <--- (CI) - o conteúdo do CI é copiado para o REM · Ex.: RDM <--- (MP(REM)) - o conteúdo da célula da MP cujo endereço está no REM é copiado para o RDM TAMANHO (EM BITS) DE UMA INSTRUÇÃO PROBLEMA DE PROJETO: Escolha do tamanho das instruções Da escolha do tamanho das instruções depende : · tamanho da memória · tamanho das células da MP · velocidade de acesso · organização do barramento de dados. A solução desta equação é complexa. Basicamente, o projetista decide entre fatores como economia de espaço em memória, processamento mais rápido das instruções ou um conjunto de instruções mais completo e poderoso: Maior Conjunto Instruções --> requer muitas instruções (para atendimento a diferentes aplicações) --->muitos bits por opcode --> requer instruções completas ---> muitos bits para operandos --> requer hardware mais complexo ---> processamento de instruções mais lento CICLO DE INSTRUÇÃO Primeiramente, o programa a ser executado precisa ser carregado (armazenado) na MP, o que é feito pelo Sistema Operacional, que também se encarrega de informar à UCP onde o programa começa. O Sistema Operacional faz isto "setando" o Contador de Instruções (isto é, colocando no CI o endereço da MP onde está localizada a primeira instrução daquele programa). A partir daí se realiza o processamento automático, executando-se as instruções seqüencialmente uma a uma, o que é obtido através do incremento automático do CI. Obs: Se o programa inclui uma instrução de desvio, o fluxo seqüencial pode ser alterado. A UCP não diferencia um dado de uma instrução. A UCP não "executa" dados devido ao conteúdo do CI, que é incrementado pelo tamanho da instrução e fica sempre apontando para a próxima instrução. Mas se em um programa houver uma instrução de desvio para um endereço em que esteja contido um dado, a UCP interpretaria o valor binário do dado como se fosse o código de uma instrução, tentaria executar e o resultado seria imprevisível. 1 - A UCP busca o código de operação na MP e armazena no Registrador de Instrução da UC Fase: Busca da instrução - (Instruction Fetch) - ciclo de busca RI <--- (CI) Micro-operações: - a UC lê o conteúdo do CI (endereço da próxima instrução ) e coloca o endereço no REM; - a UC envia um sinal à memória de operação de leitura (memory read), via barramento de controle; - a memória lê o endereço que está no REM, via barramento de endereços, e busca o conteúdo da célula referenciada; - a memória coloca no RDM, via barramento de dados, o conteúdo da célula lida; - a memória envia à UC, via barramento de controle, um sinal de "leitura concluída"; - a UC transfere o código de operação (o conteúdo do RDM) ao RI. 2 - A UC (decodificador de instruções) decodifica o Código de Operação. Fase: Busca da instrução - (Instruction Fetch) - ciclo de busca Micro-operações: - o Decodificador de Instruções decodifica o opcode; - o Decodificador de Instruções determina quantas células a instrução ocupa; - a UC incrementa o CI para apontar para a próxima instrução: CI <--(CI + n), onde n = nº de células que a instrução ocupa. - a UC incrementa o REM para apontar para o operando: REM <--(REM + 1); 3 - A UC busca (se houver) o(s) operando(s) Fase: Busca de operandos (Operand Fetch) - ciclo de execução RI <--- (Op) Micro-operações: - a UC envia um sinal à memória de operação de leitura (memory read), via barramento de controle; - a memória lê o endereço que está no REM, via barramento de endereços, e busca o conteúdo da célula referenciada; - a memória coloca no RDM, via barramento de dados, o conteúdo da célula lida; - a memória envia à UC, via barramento de controle, um sinal de "leitura concluída"; - a UC transfere o operando (o conteúdo do RDM) ao RI. * Se o operando é o próprio dado: -- a UC transfere o dado (o conteúdo do RDM) ao ACC. -- vai para operação 4; caso contrário: * Se o operando é um ponteiro para onde o dado está armazenado: -- a UC coloca no REM o endereço de onde o dado está armazenado; -- a UC envia um sinal à memória de operação de leitura (memory read), via barramento de controle; -- a memória lê o endereço que está no REM, via barramento de endereços, e busca o conteúdo da célula referenciada; -- a memória coloca no RDM, via barramento de dados, o conteúdo da célula lida; -- a memória envia à UC, via barramento de controle, um sinal de "leitura concluída"; -- a UC transfere o dado (o conteúdo do RDM) ao ACC; -- vai para operação 4. 4 - A UC comanda a execução da instrução (a operação é executada sobre o dado). Fase: Execução da instrução - ciclo de execução - UAL executa a instrução. 5 - Se o programa tiver terminado, Para; senão, volta ao passo 1.