590 likes | 682 Views
Processador MAC-1. Arquitectura. Processador MAC-1. Desenvolvido por Andrew Tanenbaum para fins didácticos Arquitectura muito simples, útil para perceber uma série de conceitos que também são válidos em processadores mais complexos Processador virtual
E N D
Processador MAC-1 Arquitectura
Processador MAC-1 • Desenvolvido por Andrew Tanenbaum para fins didácticos • Arquitectura muito simples, útil para perceber uma série de conceitos que também são válidos em processadores mais complexos • Processador virtual • Não existe implementação comercial em hardware • Existem simuladores (máquinas virtuais) que permitem executar programas para este processador
Processador MAC-1 • Principais características: • Possui 12 linhas para endereçar a memória • Espaço de endereçamento = 212 = 4K endereços • Palavras de 16 bits • Um datapath de 16 bits • 16 registos para uso interno • 2 registos para comunicação com o exterior (memória) • Uma ALU e um bloco de deslocamento • Instruções de 16 bits • Unidade de controlo multi-ciclo (microprogramada)
Arquitectura MAC-1 • Principais registos • AC (Acumulador)Guarda o resultado das operações • PC (Program Counter)Guarda o endereço da próxima instrução a ser executada • IR (Instruction Register)Guarda a instrução que vai ser executada • SP (Stack Pointer)Guarda o endereço do topo da pilha
Arquitectura MAC-1 • Registos de comunicação com o exterior • MDR (Memory Data Register)Guarda os dados recebidos / a enviar • LDR – Controlo de carregamento do BUS C • RD / WR – Carregamento / Output enable para o exterior (também são ligados à memória) • MAR (Memory Adress Register)Guarda endereços • LAR – Controlo de carregamento do BUS B
Unidade funcional MAC-1 • ALU • 2 variáveis de controlo – F1e F0 • 2 flags (ou bits deestado) • N – indica se o resultado é negativo • Z – indica se o resultado é zero • Deslocamento • 2 variáveis de controlo – H1 e H0 • Permite deslocar para esquerdaou para a direita
Organização da memória no MAC-1 • 12 bits para endereçamento • ou seja, 4K=4096 endereços • Dividido em: • Programa • Instruções (código-máquina) • Variáveis globais, constantes • Pilha (ou Stack) • Dados temporários • Variáveis locais • I/O • Escrita de caracteres no écran • Leitura de caracteres do teclado Memória
Unidade de controlo MAC-1 • O programa encontra-se carregado em memória • A unidade de controlo acede à memória para ler cada instrução • O endereço da instrução encontra-se num registo especial – o Program Counter(PC) • A leitura da instrução designa-se fetch (busca) • Durante o fetch, enquanto se acede à memória o PC é incrementado, ou seja, PC ← PC + 1 • Isto para ficar “preparado” para a próxima instrução • Depois do fetch procede-se então à execução da instrução
Unidade de controlo MAC-1 • Unidade multi-ciclo ou microprogramada • Um ciclo para realizar o fetch… • … e n de ciclos para executar a instrução • Em cada um dos n ciclos de execução aplica-se uma palavra de controlo ao datapath • Algumas instruções são simples • sequência de 1 ou 2 palavras de controlo • Outras podem ser mais complicadas • sequência mais longa de palavras de controlo para executar a instrução
Execução de uma instrução EXECUÇÃO 3. Palavra de controlo 4. Flags 1. Endereço de instrução FETCH 2. Instrução
Processador MAC-1 Linguagem assembly
Assembly MAC-1 • Endereçamento imediato • Carregamento de constantes c é qualquer valor inteiro entre 0 e 4095 (12 bits)
Assembly MAC-1 • Endereçamento directo • Usado para aceder a variáveis globais • Operações I/O (leitura e escrita de caracteres) p é a posição de memória que se pretende acederPode ser um valor inteiro entre 0 e 4095 (12 bits)
Assembly MAC-1 Exemplo – endereçamento directo // Código em java public class Exemplo { // Má programação, necessária para explicar o // endereçamento directo... public static int x = 10; public static int y = 15; public static void main(String[] args) { x = x + y; } }
Assembly MAC-1 Exemplo – endereçamento directo Registos Memória # Código MAC-1 jump main x: 10 y: 15 main: lodd x addd y stod x halt 3 4 5 6 7 0 jump 3 PC 1 0 25 10 0 10 25 AC 1 15 2 lodd 1 3 addd 2 4 stod 1 5 halt 6 ... 7
Se x for menor que 0, salta para aqui Assembly MAC-1 • Instruções de salto • Diz-se que há um salto quando a próxima instrução a executar não é a seguinte • Ou seja, não é a instrução que se encontra na posição PC+1 • Fazendo uma analogia com a programação: if (x >= 0) x = 1; else x = -1; y = x;
Assembly MAC-1 • Instruções de salto • Implementação de condições if…else • Envolvidas em ciclos (for, while) x é o endereço para o qual o programa salta em caso de salto Pode ser qualquer valor inteiro entre 0 e 4095 (12 bits)
Assembly MAC-1 Exemplo – utilização de saltos em condições // Em Java : ... if (x >= 0) y = x; else y = 0; ... # Em MAC-1: ... lodd x if:jneg else stod y jump cont else: loco 0 stod y cont:...
Assembly MAC-1 • Implementação de ciclos • Ciclo ‘while’ # Em MAC-1: ... while: lodd i subd c jpos cont ... # xpto loco 1 # addd i # stod i# i = i + 1 jump while cont:... // Em Java : ... while (i < c) { ... // xpto i = i + 1; } ...
Assembly MAC-1 • Ciclo ‘for’ # Em MAC-1: ... loco 0 # stod i # i = 0 for: lodd i subd c jzer cont ... # xpto loco 1 # addd i # stod i# i++ jump for cont:... // Em Java : ... for (i=0; i!=c; i++) { ... // xpto } ...
Processador MAC-1 A pilha: chamadas a procedimentos
A pilha • Durante a execução dos programas são normalmente invocados procedimentos • Cada procedimento pode possuir: • Variáveis locais (válidas apenas dentro do procedimento) • Argumentos (“passados” ao procedimento) • Este tipo de dados são criados num espaço da memória designado por pilha (ou stack) • Sendo assim, a pilha é utilizada para guardar: • Argumentos passados aos procedimentos • Variáveis locais dos procedimentos • Endereços de retorno dos procedimentos • Outros dados de carácter temporário
A pilha • Invocação de procedimentos • Do lado da invocação: • Colocar os argumentos na pilha • Invocar o procedimento • Descartar os argumentos da pilha • Dentro do procedimento: • Criar as variáveis locais (colocando-as na pilha) • Executar o código do procedimento • Destruir as variáveis locais (descartando-as da pilha) • Retornar do procedimento
A pilha • Retorno dos procedimentos • Quando é invocado um procedimento, é colocado na pilha o valor guardado no Program Counter. • Quando o procedimento retorna, é lido da pilha o valor de PC armazenado anteriormente. • Em princípio a função devolve um único valor • O valor é devolvido através do Acumulador (AC) • As variáveis locais e os argumento são acedidos através de endereçamento local • Endereços calculados com base no valor guardado no Stack pointer (SP)
Assembly MAC-1 • Invocação/retorno de procedimentos Instruções: x é qualquer valor inteiro entre 0 e 4095 (12 bits) ou uma label que represente um endereço
Assembly MAC-1 • Manipulação básica da pilha Instruções: n é qualquer valor entre 0 e 255 (8 bits)
Assembly MAC-1 • Endereçamento local Instruções: n é qualquer valor entre 0 e 255 (8 bits)
Assembly MAC-1 Exemplo:uma função que calcula a soma de dois números publicclassExemplo { public static int s = 0; // s – variável global publicstaticint soma( finalint x, finalint y) { return x + y; } publicstaticvoidmain(String[]args) { s = soma(10, 15); } }
Assembly MAC-1 Código MAC-1 jump main s: 0 main:loco 10 # colocar os argumentos no stack: push # passar o 10 (1º argumento) loco 15 push # passar o 15 (2º argumento) call soma# chamar a rotina insp 2 # descartar os argumentos stod s # guardar o valor em s halt soma: lodl 2 # carregar x (da pilha) addl 1 # somar a y (da pilha) retn # retornar (em AC está x+y)
SP SP SP Assembly MAC-1 Exemplo (evolução da pilha) Logo após o ‘call’ jump main s: 0 main: loco 10 push loco 15 push call soma insp 2 stod s halt soma: lodl 2 addl 1 retn Argumentos a passar a ‘soma’. Colocados na pilha antes de se fazer ‘call’. Depois de ‘retn’ End. Ret. (7) 15 Depois de ‘insp 2’ 10 ... início
Programação MAC-1 • Exemplo: Soma dos N primeiros números Pretende-se fazer uma função que calcula a soma dos números inteiros entre 1 e N • N é o argumento passado à função
Programação MAC-1 • Possível solução:usar uma variável local para ir acumulando a soma. // Código da função (em Java) publicstaticint soma_N(finalint n ) { int soma = 0, i; for ( i=1; i<=n; i++) { soma = soma + i; } return soma; }
Programação MAC-1 jump main n:10 # exemplo main: lodd n push call soma_N# soma_N(10) insp 1 halt # soma_N(n) soma_N: loco 0 push # soma=0 loco 1 push # i=1 ciclo: lodl 3 subl 0 # n-i jneg ret# while n-i>=0 lodl 1 addl 0 stol 1 # soma=soma+i loco 1 addl 0 stol 0 # i=i+1 jump ciclo ret: lodl 1 # AC=soma insp 2 retn Organização da pilha dentro de ‘soma_N’ i SP soma End. Ret. n
Programação MAC-1 • Exemplo: Divisão inteira No MAC-1 não existe nenhuma instrução para dividir… Vamos fazer uma função que calcule o resultado da divisão inteira entre dois números inteiros positivos. • D é o dividendo • d é o divisor • q é o quociente
Programação MAC-1 • Possível solução:utilizar o método das subtracções sucessivas: // Possível código (em Java) publicstaticint div(int D, finalint d ) { int q = 0; while (D >= d) { q = q + 1; D = D - d; } return q; }
Programação MAC-1 jump main main: loco 11 push loco 5 push call div# div(11,5) insp 2 halt # div(D,d) div: loco 0 push # q=0 ciclo: lodl 3 subl 2 jneg ret# while D>=d loco 1 addl 0 stol 0 # q=q+1 lodl 3 subl 2 stol 3 # D=D-d jump ciclo ret: lodl 0 # AC=q insp 1 retn Organização da pilha dentro de ‘div’ q SP End. Ret. d D
Programação MAC-1 • Exemplo: potências de 2 Implementar uma função que calcula 2n: ‘n’ é o argumento passado à função. // Pseudo-código int power2(final int n) { int p=1; for (int i=0, i!=n; i++) p=2*p; return p; }
Programação MAC-1 jump main n_ex:10 # exemplo power2: lodd n_ex push call power2 insp 1 halt # power2(final int n) power2: loco 1 # criar as var. locais push # p=1 loco 0 push # i=0 ciclo: lodl 0 subl 3 jzerret_p # i-n==0? lodl 1 addl 1 stol 1 # p=p+p (p=2*p) loco 1 addl 0 stol 0 # i=i+1 jump ciclo ret_p:lodl 1 # AC=p (valor a devolver) insp 2 # descartar as locais retn Organização da pilha em ‘power2’ i SP p End. Ret. n
Processador MAC-1 Endereçamento indirecto
Assembly MAC-1 • Endereçamento indirecto no MAC-1 • Serve para aceder a elementos de vectores ou matrizes • Basicamente acede-se à posição de memória indicada em AC Instruções:
PSHI Assembly MAC-1: PSHI
POPI Assembly MAC-1: POPI
Assembly MAC-1: PSHI e POPI • Em suma: • PSHIcoloca no topo da pilha o valor que está na posição de memória indicada por AC • SP ← SP – 1 • M[SP] ← M[AC] • POPIcoloca na posição de memória indicada por AC o valor que está no topo da pilha • M[AC] ← M[SP] • SP ← SP + 1
Programação MAC1 • Exemplo:calcular a soma de todos os elementos de um vector m // Pseudo-código int m[5] = {1, 2, 5, 7, 2}; voidmain() { inti=0, soma = 0; while( i!=5 ) { soma = soma + m[i]; i = i + 1; } }
soma SP i m[i] SP soma i Programação MAC1 jump main m:1 2 5 7 2 # valores guardados no vector m n_elem:5 # numero de elementos main: loco 0 # criar as variáveis locais: push # i = 0 push # soma = 0 ciclo: lodd n_elem subl 1 jzerfim # 5-i=0? loco m # calcula a posição do i-ésimo elemento, addl 1 # em AC fica o endereço da posição m+i pshi # coloca na pilha o valor que está na posição m+i (m[i]) pop # tira m[i]da pilha e põe no AC addl 0 stol 0 # soma = soma + m[i] loco 1 addl 1 stol 1 # i=i+1 jump ciclo fim:lodl 0 # vai acabar com AC = soma insp 2 halt
Programação MAC-1 • Passagem de argumentos • Como vimos atrás, as chamadas e retorno das rotinas são feitas através das instruções • call e retn • Consideram-se também duas formas diferentes de passagem de argumentos a uma rotina: • Passagem por valoro valor do argumento a passar à rotina é colocado na pilha • Qualquer alteração a esse valor só é válida dentro da rotina • Passagem por referênciaa posição de memória onde estão os dados é colocada na pilha e passada à rotina • Dentro da rotina, se forem alterados os dados referenciados nessa posição, essa alteração permanece válida após o retorno
Programação MAC-1 • Exemplo: mostrar vector Fazer uma função que mostre no écran os elementos de um vector, assumindo que são valores inteiros entre 0 e 9 • Para aceder aos valores armazenados num vector, é conveniente a utilização de endereçamento indirecto O procedimento deverá receber como argumentos: • Uma referência para o primeiro elemento do vector • i.e., a posição do primeiro elemento • O comprimento do vector • i.e., o número de elementos do vector
Programação MAC-1 • Exemplo: mostrar vector // Possível código Java public static void mostra(int[] vector,final intlength) { for (int i=0; i!=length; ++i) { System.out.println(vector[i]); } } Nota: em Java não seria necessário o comprimento do vector – poderia fazer vector.length. Só aparece aqui porque no MAC-1 é mesmo necessário!