Programação MAC-1 Exemplo 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; } 1 Programação MAC-1 # power2(final int n) jump main n_ex: 10 # exemplo power2: lodd n_ex push call power2 insp 1 halt power2: loco 1 push loco 0 push ciclo: Organização da pilha em ‘power2’ SP p End. Ret. n ret_p: # i=0 lodl 0 subl 3 jzer ret_p # i-n==0? lodl 1 addl 1 stol 1 # p=p+p loco addl stol jump i # criar as var. locais # p=1 1 0 0 ciclo lodl 1 insp 2 retn (p=2*p) # i=i+1 # AC=p (valor a devolver) # descartar as locais 2 Processador MAC-1 Endereçamento indirecto 3 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: Mnemónica PSHI POPI Descrição SP = SP – 1; M[SP] ← M[AC] M[AC] ← M[SP]; SP = SP + 1 Significado Push indirect Pop indirect 4 Assembly MAC-1: PSHI 0 1 2 3 4 5 6 PSHI xx 0 1 2 3 4 5 6 10 6 12 27 xx xx SP AC Pilha xx xx xx xx xx 10 6 12 27 xx xx 12 xx xx xx xx xx Pilha SP xx 3 5 Assembly MAC-1: POPI 0 1 2 3 4 5 6 SP POPI xx 0 1 2 3 4 5 6 10 6 12 27 xx xx 31 6 31 27 xx xx SP xx xx xx xx Pilha AC 10 31 Pilha xx xx xx xx xx 3 6 Assembly MAC-1: PSHI e POPI Em suma: PSHI coloca no topo da pilha o valor que está na posição de memória indicada por AC SP ← SP – 1 M[SP] ← M[AC] POPI coloca na posição de memória indicada por AC o valor que está no topo da pilha M[AC] ← M[SP] SP ← SP + 1 7 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}; void main() { int i=0, soma = 0; while ( i!=5 ) { soma = soma + m[i]; i = i + 1; } } 8 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 push push ciclo: lodd n_elem subl 1 jzer fim # 5-i=0? fim: # criar as variáveis locais: # i = 0 # soma = 0 loco addl pshi pop addl stol m 1 loco addl stol jump 1 1 1 # i=i+1 ciclo 0 0 lodl 0 insp 2 halt # # # # SP soma i calcula a posição do i-ésimo elemento, em AC fica o endereço da posição m+i coloca na pilha o valor que está na posição m+i (m[i]) tira m[i]da pilha e põe no AC # soma = soma + m[i] SP m[i] soma i # vai acabar com AC = soma 9 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 valor o valor do argumento a passar à rotina é colocado na pilha Qualquer alteração a esse valor só é válida dentro da rotina Passagem por referência a 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 10 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 11 Programação MAC-1 Exemplo: mostrar vector // Possível código Java public static void mostra( int[] vector, final int length) { 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! 12 Programação MAC-1 jump main # mostra(int[] vector, final int length) vector: 6 4 3 5 7 length: 5 mostra: loco 0 push # int i=0 char0: '0' ciclo: lodl 0 subl 2 jzer fim # i-length == 0? main: loco push lodd push call insp halt vector length lodl 3 addl 0 pshi pop mostra 2 addd stod loco stod char0 4094 ' ' 4094 # mostra no ecran Organização da pilha em ‘mostra’ loco 1 addl 0 stol 0 SP jump ciclo i End. Ret. length matriz (ref.) fim: # vector[i] na pilha # i=i+1 loco 10 # 10 é o código ascii stod 4094 # ‘fim de linha’ insp 1 retn 13