Modos de endereçamento n Registo add, sub n Imediato addi, lui, beq, bne § Base lw ou sw rt offset ($ rs ) Cod.Inst rs Cod.Inst Cod.Inst rt rs rs rt Shamt Funct Constante\endereço offset=4*i por exemplo + Registo rs=A[0] § Relativo ao PC rt rd Memória bne, beq Cod.Inst rs rt endereço do Label – PC + n . Endereço PC + Memória NOTA: Na instrução máquina teremos um endereçamento por word, nas duas últimas instruções, ou em beq, bne na 2ª instrução 08-10-2001 Aula 3 1 Endereçamento Relativo ao PC n n § Vimos já que as instruções beq e bne têm endereçamento relativo ao PC (Formato I) O campo de endereço de beq e bne tem 16 bits, para um endereço por byte na instrução assembly simbólica até (216 posições de endereço) 64 Kbytes, a adicionar ao endereço do PC (Program Counter) Vejamos a seguir os modos de endereçamento 08-10-2001 Aula 3 2 1 Estrutura da memória principal n É convencional a organização da memória em sistemas MIPS: 0x7fffffff 0x1000ffff 0x10008000 0x10000000 0x00400000 08-10-2001 Segmento da Stack Segmento dos Dados Segmento de Texto Stack segment Data segment Text segment Reservado Aula 3 3 Organização da frame de stack n Vejamos o diagrama da frame do stack. A frame da stack consiste da porção de memória entre o ponteiro de frame ($fp) e o ponteiro da stack ($sp), apontando esta para a última palavra na frame. Como a stack cresce de endereços mais altos para endereços mais baixos, o ponteiro da stack tem um endereço inferior que o endereço da frame. $fp ... Argumento 6 Argumento 5 Argumentos1-4 Endereços de memória Registos guardados Variáveis locais $sp 08-10-2001 Área dinâmica Aula 3 4 2 Saltos para endereços com 32 (28) bits n n As instruções j e jal, com o Formato J, tendo endereços imediatos, dispõem de 26 bits para se indicar o endereço da memória. As instruções j e jal usam, nas instruções máquina, endereçamento por words, logo podem indicar endereços de 28 bits=26+2 bits (até 256 Mbytes=228 posições de memória). 08-10-2001 Aula 3 5 Codificação dum programa em Assembly n Codifique um programa que copie palavras do endereço no registo $8 para o endereço no registo $9, contando o número de palavras copiadas no registo $10. O programa pàra de copiar quando encontra uma palavra igual a 0 (zero). Não é preciso preservar o conteúdo dos registos $8, $9 e $10 08-10-2001 Aula 3 6 3 Programa codificado em Assembly # Este programa copia palavras do endereço em $8 para endereço # de $9, incrementando-os até encontrar um endereço com zero main: add $10, $zero, $zero ciclo: lw $11, 0($8) # Lê a próxima palavra da origem addi $10, $10, 1 # Incrementa contador de palavras sw $11, 0($9) # Escreve no destino addi $8, $8, 4 # Avança apontador de endereço da fonte addi $9, $9, 4 # Avança apontador de endereço do destino bne $11, $0, ciclo # Avança para ciclo se palavra copiada !=0 jr $ra 08-10-2001 Aula 3 7 Introdução ao uso do simulador SPIM n n O simulador SPIM converte os programas em linguagem assembly, destinados o processador MIPS R2000/R3000, para programas objecto, obtendo-se programas em linguagem máquina. O SPIM além do assembler, possui um debugger, uma interface gráfica para várias plataformas (Spim para DOS, Xspim para Unix e PCSpim para Windows). É este simulador que vamos usar. 08-10-2001 Aula 3 8 4 Janelas do SPIM Janela de Registos Janela de Segmento de Texto Janela de Segmento de Dados Janela de Mensagens 08-10-2001 Aula 3 9 Normas para o uso do simulador PCSpim n n n O simulador é um programa base que lê outros programas em linguagem assembly, escritos por nós. Deve-se fazer o setting inicial: simulator>settings, obrigando a usar o programa trap.handler (“load trap file”) O programa base usa o nosso programa, como se fosse um procedimento, chamando-o com jal main. Termina a execução do nosso programa com jr $ra. Daí a necessidade de guardar o conteúdo do registo $ra se tivermos de usá-lo no nosso programa ou subrotinas. O nosso programa, constituindo um ficheiro *.asm, deve ser prèviamente escrito, com um editor de texto, WorkPad, NotePad ou outro editor de texto clássico, ficando com a seguinte estrutura: main: instrução 1 instrução 2 . . . fim: jr $ra 08-10-2001 Aula 3 10 5 Como carregar o nosso programa n n n n O nosso programa é carregado com o simulador PCSpim através do menu file>open indicando o directório, pastas e nome do ficheiro, por Exemplo C:\Programs\Acessories\WorkPad\PCSpim\Exerc1.asm A sintaxe do nosso programa é verificada automaticamente, e assinalados os erros. O programa, já sem erros de sintaxe, pode ser executado na totalidade (F5) ou passo a passo (F10) (”simulator>go ou simulator>single step”) Podemos verificar a correcta execução do nosso programa através do estado final dos registos e do registo PC (Program Counter). Use simulator>reload para o executar de novo depois das correcções 08-10-2001 Aula 3 11 EXERCÍCIOS n Ø Ø Vamos executar os programas já escritos em aulas anteriores: 3.1 - Escreva um programa para calcular f=(g+h)-(i-j), em que f se calcula num procedimento proc-ex, sendo os registos $a0-$a3 para as variáveis g, h, i, e j, como argumentos do procedimento e $t2 para o resultado f. 3.2 - Escreva o programa assembly correspondente ao seguinte segmento C, com i , j e k como variáveis, contidas nos registos $s3, $s4, $s5, supondo que o endereço base A[0] está no registo $s6 While ( A[i]==k) i=i+j; NOTA: Prevenir que A[i] e h tenham valores pré-estabelecidos, e que, no 1º exercício, as varáveis g, h, i, e j tenham valores previamente atribuídos 08-10-2001 Aula 3 12 6 Programa assemblado e executado com o PCSpim 08-10-2001 Aula 3 13 Programa codificado em assembly # Aula de Arquitectura de Computadores, 8/10/2001 # Cálculo de f = (g+h)-(i+j) main: addi $a0, $0, 1 # Valor inicial para registo addi $a1, $0, 2 # Valor inicial para registo addi $a2, $0, 3 # Valor inicial para registo addi $a3, $0, 4 # Valor inicial para registo add $t0, $a0, $a1 # t0 = a0 + a1 add $t1, $a2, $a3 # t1 = a2 + a3 sub $t2, $t0, $t1 # t2 = to - t1 end: jr $31 08-10-2001 Aula 3 a0=1 a1=2 a2=3 a3=4 14 7 Programa assemblado e executado com o PCSpim 08-10-2001 Aula 3 15 Resolução do Exercício 3.2 # Arquitetura de Computadores, 08\10\2001 # Traduz em assembly o segmento C: while (A[i]==k) i=i+j; main: lui $s6, 0x1000 addi $s6, $s6, 0x100 addi $t0, $0, 21 sw $t0, 0($s6) addi $t0, $0, 22 sw $t0, 4($s6) addi $t0, $0, 22 sw $t0, 8($s6) addi $s3, $0, 1 addi $s4, $0, 1 addi $s5, $0, 22 Loop: add $t1, $s3, $s3 add $t1, $t1, $t1 add $t1, $t1, $s6 lw $t0, 0($t1) bne $t0, $s5, Exit add $s3, $s3, $s4 j Loop Exit: j $ra 08-10-2001 # Carrega endereço nos 16 MSD de $s6 # Carrega valores no array A[i] # # # # # # # Carrega i=1 Carrega j=1 Carrega k=22 Obter 2 * i Obter 4 * i Se $s6=A[0], $t1=Endereço A[i] $t0=conteúdo do endereço de $t1 Aula 3 16 8