Вы находитесь на странице: 1из 51

Apostila Assembly MIPS Simulador SPIM

Aulas Prticas Laboratrio


Profa. Christiane Vilaa Pousa

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

Sumrio:
1 INTRODUO AO ASSEMBLY INTRODUO ASSEMBLY MIPS R2000 SPIM PRINCIPAIS CARACTERSTICAS CONCEITOS BSICOS EXEMPLOS ATIVIDADES PROPOSTAS 3 3 3 6 8 8 10 11 12 12 13 15 17 17 17 19 20 20 20 25 27 27 30 33 35 35

1.1 1.2 1.3 1.3.1 1.3.2 1.4 1.5 2 2.1 2.2 2.3 3 3.1 3.2 3.3 4 4.1 4.2 4.3 5 5.1 5.2 5.3 6 6.1

GERNCIA DE MEMRIA INTRODUO EXEMPLOS ATIVIDADES PROPOSTAS OPERAES LGICO/ARITMTICAS INTRODUO EXEMPLOS ATIVIDADES PROPOSTAS CONDICIONAIS E LAOS DE REPETIO INTRODUO EXEMPLOS ATIVIDADES PROPOSTAS PROCEDIMENTOS E FUNES INTRODUO EXEMPLOS ATIVIDADES PROPOSTAS ENTRADA E SADA CONSULTA DE ESTADO INTRODUO

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores 6.2 6.3 7 7.1 7.2 7.3 8 9 EXEMPLOS ATIVIDADES PROPOSTAS ENTRADA E SADA INTERRUPO INTRODUO EXEMPLOS ATIVIDADES PROPOSTAS REFERENCIAS BIBLIOGRFICAS ANEXO 35 38 39 39 44 47 48 49

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

1
1.1

Introduo ao Assembly
Introduo

O assembly uma linguagem de programao baixo nvel e permite uma representao simblica das instrues binrias do computador. A linguagem assembly chamada de linguagem de montagem e a linguagem que define instrues codificadas em zeros e uns chamada de linguagem de mquina. A linguagem assembly oferece uma representao mais prxima do programador que a linguagem de mquina, o que simplifica a leitura e escrita dos programas. Cada instruo em linguagem assembly corresponde a uma instruo de linguagem mquina, mas, em vez de ser especificada em termos de zeros e uns, especificada utilizando mnemnicos e palavras reservadas. O assembly amplamente utilizado quando temos como pr-requisito aplicaes que demandam tempo e espao pequenos. Estas aplicaes, na maioria das vezes, esto presentes em sistemas embutidos (controlador de freio ABS em carros, controladores de eletrodomsticos, celulares, etc). As aplicaes que so executadas nestes sistemas precisam responder rapidamente aos eventos, alm disso, precisam ser aplicaes que possam ser armazenadas em pequenas memrias. Vantagens Desvantagens Maior controle do sistema especfico para uma arquitetura Maior velocidade de execuo Maior nmero de linhas no programa Quantidade menor de memria gasta para Diminui o ritmo de desenvolvimento de armazenar o programa programas Poucas instrues e comandos Complexidade de anlise de erros Tabela 1 Vantagens e desvantagens da programao em assembly em relao a linguagens de alto nvel. 1.2 Assembly MIPS R2000

O MIPS (Microprocessor without Interlocked Pipeline Stages) um microprocessador desenvolvido pela MIPS Computer Systems Inc [1]. Seguindo o princpio de que a simplicidade favorecida pela regularidade, o MIPS utiliza um conjunto de instrues de tamanho fixo de 32 ou de 64 bits. Outra restrio que suas instrues aritmticas/lgicas sempre possuem trs operandos, sendo que o primeiro operando o destino (conter o resultado da operao). Estas instrues s podem manipular operandos armazenados em registradores. A memria vista como um grande vetor enderevel. Cada endereo de memria um ndice deste vetor. O endereamento da memria feito em bytes, isto quer dizer 3

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores que cada posio do vetor corresponde a um byte. Portanto, considerando um MIPS com instrues e dados de 32 bits, por exemplo, cada palavra ocupa 4 posies do vetor. Alm disso, as palavras so alinhadas, isto quer dizer que cada palavra tem um endereo mltiplo de 4. O MIPS possui uma arquitetura RISC (Reduced Instruction Set Computer). Isto significa que seu conjunto de instrues reduzido, tornando-o um processador simples em relao arquitetura da famlia dos 80X86. Esta comercialmente mais difundida em mquinas de propsito geral (computadores pessoais, servidores etc), no entanto, sua complexidade dificulta sua utilizao em disciplinas como Arquitetura de Computadores. Por ser mais simples, o MIPS adotado em livros didticos [2]. O MIPS que vamos adotar nas nossas aulas de laboratrio o MIPS R2000. As instrues e registradores deste processador so apresentados a seguir: Sintaxe Tipo Op Func Lb Rdest, Imm16(Rsrc) I 0x20 Lw Rdest, Imm16(Rsrc) I 0x23 lbu Rdest, Imm16(Rsrc) I 0x24 sb Rsrc2, Imm16(Rsrc1) I 0x28 sw Rsrc2, Imm16(Rsrc1) I 0x2b lui Rdest, Imm16 I 0x0f Transferncia de mfhi Rdest R 00 0x10 informao mflo Rdest R 00 0x12 mthi Rsrc R 00 0x11 mtlo Rsrc R 00 0x13 li Rdest, Imm16/32 la Rdest, address16/32 move Rdest, Rsrc Operaes add Rdest, Rsrc1, Rsrc2 R 00 0x20 aritmticas addi Rdest, Rsrc1, Imm16 I 08 addu Rdest, Rsrc1, Rsrc2 R 00 0x21 addiu Rdest, Rsrc1, I 09 Imm16 sub Rdest, Rsrc1, Rsrc2 R 00 0x22 subu Rdest, Rsrc1, Rsrc2 R 00 0x23 mult Rsrc1, Rsrc2 R 00 0x18 multu Rsrc1, Rsrc2 R 00 0x19 div Rsrc1, Rsrc2 R 00 0x1a divu Rsrc1, Rsrc2 R 00 0x1b abs Rdest, Rsrc Grupo Comentrio load byte load word load unsigned byte store byte store word load upper immediate move from hi move from lo move to hi move to lo load immediate load address move addition (with overflow) addition imm. (with ov.) addition (without overflow) addition imm. (without ov.) subtract (with overflow) subtract (without overflow) multiply unsigned multiply divide unsigned divide absolutevalue

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores mul Rdest, Rsrc1, Rsrc2 div Rdest, Rsrc1, Rsrc2 rem Rdest, Rsrc1, Rsrc2 and Rdest, Rsrc1, Rsrc2 andi Rdest, Rsrc1, Imm16 or Rdest, Rsrc1, Rsrc2 ori Rdest, Rsrc1, Imm16 xor Rdest, Rsrc1, Rsrc2 Operaes lgicas xori Rdest, Rsrc1, Imm16 e de comparao nor Rdest, Rsrc1, Rsrc2 slt Rdest, Rsrc1, Rsrc2 slti Rdest, Rsrc1, Imm16 sltu Rdest, Rsrc1, Rsrc2 sltiu Rdest, Rsrc1, Imm16 not Rdest, Rsrc sll Rdest, Rsrc1, Rsrc2 srl Rdest, Rsrc1, Rsrc2 Operaes de deslocamento de sra Rdest, Rsrc1, Rsrc2 bits rol Rdest, Rsrc1, Rsrc2 ror Rdest, Rsrc1, Rsrc2 Operaes de j address28 salto jr Rsrc beq Rsrc1, Rsrc2, address18 bne Rsrc1, Rsrc2, address18 bgez Rsrc, address18 bgtz Rsrc, address18 blez Rsrc, address18 bltz Rsrc, address18 jal address28 jalr Rsrc b address18/32 b<cnd> Rsrc1, Rsrc2, address18/32 multiply divide remainder AND AND immediate OR OR immediate XOR XOR immediate NOR set less than set less than immediate set less than unsigned set less than unsigned imm. not shift left logical shift right logical shift right arithmetic rotate left rotate right jump (absolute addr) jump register branch on equal (relative addr) branch on not equal (relative addr) br. on greater than equal zero (relative addr) br. on greater than zero (relative addr) br. on less than equal zero (relative addr) br. on less than zero (relative addr) jump and link (absolute addr) jump and link register branch inconditional (relative addr) br. on <cnd> = [gt, ge, lt, le] (relative addr) 5

R I R I R I R R I R I R R R

00 0x0c 00 0x0d 00 0x0e 00 00 0x0a 00 0x0b 00 00 00

0x24 0x25 0x26 0x27 0x2a 0x2b 00 02 03

J R I I I I I I J R

02 00 04 05 01 07 06 01 03 00

08 01* 00* 09

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores b<cnd>u Rsrc1, Rsrc2, address18/32 rfe syscall break code20 br. on <cnd> = [gt, ge, lt, le] uns (relative addr) return from exception system call break

Exceo

R R R

0x10 0x20 00 0x0c 00 0x0d

Tabela 2 Instrues do MIPS [3] Nmero do registrador 0 1 2-3 4-7 8-15 16-23 24-25 26-27 28 29 30 31

Nome $zero $at $v0-$v1 $a0-$a3 $t0-$t7 $s0-$s7 $t8-$t9 $k0-k1 $gp $sp $fp $ra

Uso Valor constante 0 Reservado para o montador Valores para resultados e avaliao de funes Argumentos Temporrios (no preservados nas chamadas de funes) Valores salvos (preservados nas chamadas de funes) Temporrios (no preservados nas chamadas de funes) Reservados para o kernel do sistema operacional Ponteiro global Ponteiro de pilha (stack pointer) Ponteiro de quadro (frame pointer) Endereo de retorno (de chamadas de funes) Tabela 3 Registradores do MIPS

1.3

SPIM

O SPIM (MIPS ao contrrio) um software simulador que executa programas escritos para os processadores MIPS R2000 e R3000. O SPIM pode ler e executar arquivos em linguagem de montagem do MIPS. Ele um sistema completo, autocontido, para executar programas do MIPS [2]. A vantagem de utilizar um simulador vem do fato de este fornecer ferramentas de visualizao e depurao dos programas que facilitam a tarefa de programao sem prejuzo da aprendizagem desta linguagem. Alm disso, o uso de um simulador torna-o independente da mquina (ou seja, no necessrio comprar um processador MIPS e podemos utilizar o simulador numa variedade de plataformas, por exemplo Windows, Mac, UNIX, etc). O SPIM possui depurador, janela de mensagens de erros e interface grfica para visualizao da execuo do programa (Figura 1).

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

Figura 1 Interface Grfica do SPIM Janela de registradores: atualizado sempre que o programa para de executar. Mostra o contedo de todos os registradores do MIPS (CPU e FPU). Janela de Mensagens: mostra as mensagens de erro, sucesso etc. Ou seja, apresenta mensagens sobre a execuo do programa. Segmentos de Dados: apresenta os endereos e contedos das palavras que esto na memria. Segmento de Texto: mostra as instrues do programa e as instrues do kernel do MIPS. Cada instruo do programa fonte apresentada em uma linha da janela. Veja o exemplo a seguir:

[0x00400000] 0x8fa40000 lw $4,0($29) ; 89: lw $a0, 0($sp)


[0x00400000] - endereo de memria onde a instruo est. 0x8fa40000 - Codificao numrica da instruo do MIPS lw $4,0($29) - instruo assembly do MIPS (com endereos reais de memria e registrador) O que est depois do ponto e vrgula a linha e a instruo do cdigo fonte.

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores 1.3.1 Principais caractersticas

O simulador pode carregar e executar programas em linguagem assembly das arquiteturas R2000 e R3000. O processo atravs do qual um cdigo fonte em linguagem assembly traduzido em um executvel dividido em duas etapas (Figura 2): 1. montagem, implementada pelo montador (assembler) 2. ligao, implementada pelo ligador (link-editor) O montador realiza a traduo de um mdulo de linguagem assembly em cdigo mquina. Um programa pode conter diversos mdulos, cada um deles como parte do programa. Isto acontece com freqncia, quando se constri uma aplicao a partir de vrios arquivos. A sada do montador um arquivo objeto para cada arquivo fonte. Os arquivos objetos contm cdigo mquina. A traduo de um arquivo no fica completa caso o arquivo utilize um smbolo (um label) que definido num arquivo diferente ou parte de uma biblioteca. aqui que entra o ligador. O seu objetivo principal resolver referncias externas. Em outras palavras, o ligador ir trocar um smbolo utilizado no arquivo fonte com a sua definio encontrada em um arquivo ou biblioteca. A sada do ligador um arquivo executvel.

Figura 2 Processo de traduo [2] 1.3.2 Conceitos Bsicos

Alguns conceitos bsicos para iniciar o uso do simulador SPIM: Comentrios: so importantes quando se trabalha com linguagens de baixo nvel, pois ajudam no desenvolvimento e depurao dos programas e so muito utilizados. Os comentrios comeam com o caractere "#" e terminam no final da linha. Identificadores: so seqncias de caracteres alfanumricos, underscores (_) ou pontos (.) que no comeam por um nmero. Os mnemnicos so palavras reservadas da linguagem e no podem ser usadas como identificadores.

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

Rtulos (labels): Identificadores que se encontram no princpio de uma linha e que so sempre seguidos de dois pontos. Servem para dar um nome ao elemento definido em um endereo de memria. Pode-se controlar o fluxo de execuo do programa criando saltos para os rtulos. Pseudo-instrues. Instrues que o assembler interpreta e traduz em uma ou mais micro-instrues (em linguagem mquina). Diretivas: Instrues que o assembler interpreta a fim de informar ao processador a forma de traduzir o programa (Tabela 4). Por exemplo, a diretiva .text informa que se trata de uma zona de cdigo; a diretiva .data indica que se segue uma zona de dados. So identificadores reservados, e iniciam-se sempre por um ponto. O SPIM no distingue as vrias partes do segmento de dados (.data, .rdata e .sdata).

Os nmeros nas instrues assembly do MIPS esto na base 10 por padro. Se eles forem precedidos por 0x, sero interpretados como hexadecimais. Logo, 256 e 0x100 indicam o mesmo valor. As strings no SPIM so delimitadas com aspas (). Caracteres especiais nas strings seguem a conveno da linguagem C:

.align n

nova linha (\n) tabulao (\t) aspas (\") Alinha o prximo dado em um limite de 2n bytes. Por exemplo, .align 2 alinha o prximo valor em um limite de word. .align 0 desativa o alinhamento automtico das diretivas .half, .word, .float e .double at a prxima diretiva .data ou .kdata. Armazena a string str na memria, mas no a termina com nulo. Armazena a string str na memria e a termina com nulo. Armazena os n valores em bytes sucessivos da memria. Itens subseqentes so armazenados no segmento de dados. Se o argumento opcional end estiver presente, os itens subseqentes so armazenados a partir do endereo end. Armazena os n nmeros de preciso dupla em ponto flutuante em locais de memria sucessivos. Declara que o dado armazenado em sym possui tamanho bytes de extenso e um rtulo global. Essa diretiva permite que o montador armazene o dado em uma parte do segmento de dados que acessado eficientemente por meio do registrador $gp. Armazena os nmeros de preciso simples em ponto flutuante nos locais de memria sucessivos. Declara que o rtulo sym global e pode ser referenciado a partir de outros arquivos.

.ascii str .asciiz str .byte b1,..., bn .data <end>

.double d1, ..., dn .extern sym tamanho

.float f1,..., fn .globl sym

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores
.half h1, ..., hn .kdata <end>

.ktext <end>

.set noat e .set at

.space n .text <end>

.word w1,..., wn

Armazena as n quantidades de 16 bits em halfwords sucessivas da memria. Itens de dados subseqentes so armazenados no segmento de dados do kernel. Se o argumento opcional end estiver presente, itens subseqentes so armazenados a partir do endereo end. Itens subseqentes so colocados no segmento de texto do kernel. No SPIM, esses itens s podem ser instrues ou palavras (ver a diretiva .word, mais adiante). Se o argumento opcional end estiver presente, os itens subseqentes so armazenados a partir do endereo end. A primeira diretiva impede que o SPIM reclame sobre instrues subseqentes que utilizam o registrador $at. A segunda diretiva reativa a advertncia. Como as pseudo-instrues se expandem para o cdigo que usa o registrador $at, os programadores precisam ter muito cuidado ao deixar valores nesse registrador. Aloca n bytes de espao no segmento atual (que precisa ser o segmento de dados no SPIM). Itens subseqentes so colocados no segmento de texto do usurio. No SPIM, esses itens s podem ser instrues ou palavras (ver a diretiva .word a seguir). Se o argumento opcional end estiver presente, os itens subseqentes so armazenados a partir do endereo end. Armazena as n quantidades de 32 bits em palavras de memria sucessivas. Tabela 4 - Diretivas usadas no SPIM [2]

1.4

Exemplos

Exemplo 1: usando um editor qualquer, crie o programa listado a seguir e salve-o com o a extenso .asm. No link [4] voc poder encontrar mais informaes sobre as instrues do MIPS.
.data msg1: .asciiz "Digite um numero inteiro: " .text .globl main No interior do main existem algumas chamadas (syscalls) que iro alterar o valor do registrador $ra o qual contm inicialmente o endereo de retorno do main. Este necessita ser guardado. addu $s0, $ra, $0 # guardar o registrador $31 em $16 li $v0, 4 # chamada sistema print_str la $a0, msg1 # endereo da string a imprimir syscall # obter o inteiro do utilizador li $v0, 5 # chamada sistema read_int syscall # coloca o inteiro em $v0 # realizar clculos com o inteiro addu $t0, $v0, $0 # mover o nmero para $t0

# # # #

main:

10

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores
sll $t0, $t0, 2 # imprimir o resultado li $v0, 1 # chamada sistema print_int addu $a0, $t0, $0 # mover o nmero a imprimir para $a0 syscall # repr o endereo de retorno para o $ra e retornar do # main addu $ra, $0, $s0 # endereo de retorno de novo em $31 jr $ra # retornar do main

O contedo do registrador $ra guardado no registrador $s0. O registrador $ra armazena o endereo de retorno do MAIN. Como o programa realiza outras chamadas de funes (systems calls) torna-se necessrio salvar o endereo de retorno do MAIN em outro registrador para que o MAIN consiga retornar. O funcionamento completo de funes ser apresentado mais tarde em sala de aula. Aqui, o importante se lembrar de salvar o valor de $ra antes de fazer qualquer chamada de procedimentos. 1.5 Atividades Propostas 1- Para o programa anterior mostre o programa gerado a partir dele pelo SPIM. Por que o nmero de instrues apresentado na janela de segmento de texto do SPIM maior que o programa original? 2- Modifique o programa anterior para que ele apresente o resultado da operao com o inteiro na tela na forma: RESULTADO = valor 3- Implemente um programa que permita realizar a soma de dois nmeros inteiros. 4- Implemente um programa que permita realizar a subtrao de dois nmeros ponto flutuante [5]. 5- Utilize as operaes de depurao do simulador.

11

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

2
2.1

Gerncia de Memria
Introduo

No assembly, diferentemente das outras linguagens de programao, toda a movimentao de dados na memria deve ser gerenciada pelo programador. Para isso existem instrues especficas que veremos na aula de hoje. Considerando o processador MIPS, a unidade base de endereamento o byte. Porm, mais comum trabalharmos com o que chamamos de palavra ou word (32 bits). A palavra tem a mesma dimenso do barramento do MIPS. Desta forma, uma leitura qualquer na memria do MIPS ter como resultado 4 bytes de dados ou de instrues. Os endereos no MIPS esto sempre dispostos em posies mltiplas de quatro. Na figura 1 apresentamos a representao da memria do MIPS. Como podemos observar a memria do MIPS dividida em alguns segmentos. Para ns os mais importantes so o segmento de texto e de dados. No segmento de texto os programas so armazenados (conjunto de instrues). J no segmento de dados, os dados relativos aos programas que esto sendo executados, so armazenados.

Figura 1 Organizao da Memria As faixas de endereos: 0x00000000 0x00400000: reservado ao sistema operacional. 0x00400000 0x10000000: reservado para armazenamento das instrues dos programas que esto sendo executados no momento. O SPIM sempre vai pedir

12

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores o usurio que informe o endereo inicial para o programa antes de comear a sua execuo. O padro do SPIM comear no endereo 0x00400000. 0x10000000: reservado para armazenamento de dados alocados estaticamente. As variveis de um programa, vetores estticos etc so armazenadas nesta parte da memria. No SPIM, usamos a diretiva .data para mostrar a faixa de cdigo que apresenta os dados que devem ser alocados estaticamente. O restante da memria fica com pilha e o heap: estas partes da memria so usadas para armazenar dados que so alocados dinamicamente. Exemplos

2.2

Para tornar a aula mais prtica vamos trabalhar as explicaes com exemplos prticos. Exemplo 1: Usando um editor qualquer, crie o programa abaixo:
.data # segmento de dados palavra1: .word 13 #decimal palavra2: .word 0x15 #hexadecimal

A diretiva .data apresenta que o cdigo que vier abaixo um segmento de dados (declarao de dados). O correto sempre usar .data ENDERECO, porm, se nada informado o SPIM comea pelo endereo padro 0x10010000. A diretiva .word informa que uma seqncia de palavras pode ser reservada. Neste caso, o rtulo possui o endereo a primeira palavra. Exemplo 2: Usando um editor qualquer, crie o programa abaixo:
.data 0x10000000 # segmento de dados vetor: .word 5 #decimal .text # Programa principal main: addiu $t0,$0,0x10000000 #Guardando o endereo inicial do vetor li $t1,10 # atribuindo o valor 10 ao registrador $t1 sw $t1,0($t0) #armazenando na memria o valor do registrador $t1 li $t1,11 sw $t1,4($t0) li $t1,12 sw $t1,8($t0) li $t1,13 sw $t1,12($t0) li $t1,14 sw $t1,16($t0)

Este programa cria um vetor de cinco posies no segmento de dados e atribui a cada uma das posies do vetor os valores 10, 11, 12, 13, 14. Para fazer isso usamos as instrues li e sw. A instruo li quer dizer load immediate, ou seja, carregar no registrador destino um valor de 16/32 bits (constante). As instrues sw e addiu j conhecemos.

13

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores Exemplo 3: Usando um editor qualquer, crie o programa abaixo:
.data dado: .byte 0x10 # segmento de dados #hexadecimal

Neste caso armazenamos no endereo padro do SPIM um byte em uma palavra e o valor deste byte 0x10. Verifique isso na janela de segmento de dados no SPIM.

Figura 2 Segmento de dados depois da execuo do programa Exemplo 4: Usando um editor qualquer, crie o programa abaixo e execute-o:
.data # segmento de dados dado: .byte 0x10,0x20,0x30,0x40 #hexadecimal dado2: .word 0x10203040 .text main: # Start of code section

Exemplo 5: Usando um editor qualquer, crie o programa abaixo e execute-o:


.data cadeia: .ascii "abcde" .byte 0xff .text main: # Data declaration section

# Start of code section

Exemplo 6: Usando um editor qualquer, crie o programa abaixo e execute-o:

14

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores
.data # Data declaration section palavra1: .word 0x20 espaco: .space 8 palavra2: .word 0x30 .text main: # Start of code section

A diretiva .space reserva n bytes na memria e colocar o valor zero nas posies. Exemplo 7: Usando um editor qualquer, crie o programa abaixo e execute-o:
.data # Data declaration section pal1: .word 0x10203040 pal2: .space 4 pal3: .word 0xffffffff .text main: # lw $s0, pal1($0) # # sw $s0, pal2($0) # # Start of code section carrego o que esta no endereco do rotulo pal1, neste caso eh o valor 0x10203040 armazena o contedo de $s0 no endereco de memoria pal2+0

2.3

Atividades Propostas 1- Explique os resultados obtidos no exemplo 4. O que foi armazenado no segmento de dados? Por que os valores ficaram trocados? 2- Crie um programa que permita um usurio preencher um vetor de 3 posies. 3- Crie um programa que escreva no monitor o seu nome completo. 4- Mostre os resultados do exemplo 5 (segmento de dados). Como identificar as letras no segmento de dados? 5- Altere o programa anterior para que ele use a diretiva .asciiz. Qual a diferena? 6- Explique os resultados obtidos com o exemplo 6. Qual o contedo do segmento de dados? Por qu? 7- Crie um programa que recebe dois nmeros inteiros e armazena nos registradores $s1 e $s0. Depois faa com que os contedos destes dois registradores v parar em endereos consecutivos no segmento de dados. 8- Altere o programa do exemplo 7 para que o valor de pal3 passe a ser o valor contido em pal2.

15

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores 9- Crie um programa que permita preencher uma matriz 3x3 de inteiros a partir do endereo 0x10000004. Depois esta matriz deve ser apresentada na tela do monitor. Use as chamadas de sistemas para conseguir realizar estas operaes.

16

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

3
3.1

Operaes Lgico/Aritmticas
Introduo

As operaes lgico/aritmticas so base de qualquer processador. Por isso o nmero de instrues e formato mudam bastante em cada um dos processadores que existem. As instrues aritmticas so constitudas por operaes de soma (add, addi, addiu, addu), subtrao (sub e subu), multiplicao (mult e multu) e diviso (div e divu). Todas estas instrues operam apenas com registradores e valores constantes. No permitido no MIPS que instrues aritmticas acessem diretamente a memria. Porm, em outros processadores (famlia 80x86) isso possvel. Algumas das instrues acima terminam com u essas instrues so usadas quando queremos capturar exceo de overflow. Ou seja, quando alguma instruo gerou um resultado maior que 32 bits. Alm das operaes aritmticas existem ainda as operaes lgicas. Elas so: or, ori, and, andi, xor, xori, nor, nori, not e neg. Assim, como as instrues aritmticas estas instrues trabalham apenas com registradores e valores constantes. Existem trs instrues que fazem parte do conjunto de instrues lgico/aritmticas apesar de no serem propriamente de nenhum destes dois tipos. Estas instrues so responsveis por realizar rotao dos bits dentro de um registrador. Elas so sll, srl, sra, rol e ror. Estas instrues trabalham apenas com registradores. importante observar que algumas destas instrues so apenas pseudo-instrues do MIPS. Ou seja, o hardware do MIPS no consegue execut-las diretamente. Quando instrues como essas so encontradas pelo SPIM ele as converte em instrues nativas do MIPS. 3.2 Exemplos

Para exemplificar o uso destas instrues vamos apresentar alguns exemplos. Exemplo 1: Crie um arquivo com o cdigo do programa abaixo. Lembre-se que no SPIM os valores contidos no segmento de dados e nos registradores esto no formato hexadecimal.
.data numero: .word 2147483647 .text main: lw $t0,numero($0) # armazenando um nmero na memria #programa principal #acessando o numero armazenado na memria # e armazenando em $t0

17

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores
addiu $t1,$t0,1 # somando o valor contido em $t0 2147483647 # com 1 e armazenando em $t1 2147483648

Exemplo 2: Crie um arquivo com o cdigo do programa abaixo.


.data num1: .word 0x80000000 num2: .word 1 num3: .word 1 .text main: lw $t0,num1($0) lw $t1,num2($0) subu $t0,$t0,$t1 lw $t1,num3($0) subu $t0,$t0,$t1 sw $t0,num1($0) # carregando $t0 com o valor de num1 #carregando $t1 com o valor de num2 #subtraindo de $t0 o valor de $t1 #armazenando em $t1 o valor do num3 #subtraindo de $t0 o valor de $t1 # armazenando o valor de $t0 na # na memria (endereo do num1) #segmento de dados # armazenando o valor 2147483648 no num1 # num2 e num3 ficam com os valores 1

#segmento de texto

Exemplo 3: Crie um arquivo com o cdigo do programa abaixo.


.data num: .word 0x3ff41 .space 4 .text main: lw $t0,num($0) # 0xfffe em binrio 0...0 1111 1111 1111 1110 andi $t1,$t0,0xfffe sw $t1,num+4($0)

Exemplo 4: Crie um arquivo com o cdigo do programa abaixo.


MSG: .data .asciiz "Digite um valor inteiro" .text addiu $s0,$ra,0 li $v0, 4 # chamada sistema print_str la $a0, MSG # endereo da string a imprimir syscall # obter o inteiro do utilizador li $v0, 5 # chamada sistema read_int syscall # coloca o inteiro em $v0 # realizar clculos com o inteiro addi $t0,$v0,0 sll $t0,$t0,3 # multiplica $t0 por 2 elavado a 3 li $v0, 1 # chamada sistema print_int addu $a0, $t0, $0 # mover o nmero a imprimir para $a0 syscall # repr o endereo de retorno para o $ra e retornar do # main

main:

18

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores
addu $ra, $0, $s0 # endereo de retorno de novo em $31 jr $ra # retornar do main

A instruo sll funciona como uma multiplicao de um nmero por 2i. 3.3 Atividades Propostas 1- Modifique o primeiro exemplo para que o resultado da operao de soma seja impresso na tela do monitor. 2- Altere o exemplo 2 para que o valor original de num1 no seja perdido. 3- Se no programa do exemplo 2 usssemos a instruo sub no lugar da instruo subu, o resultado seria correto? Por qu? 4- Escreva um programa em assembly que permita resolver a equao z= (y-x) + (y*x). Os valores para as variveis devem ser atribudos pelo usurio. 5- Escreva um programa em assembly do MIPS que armazene um vetor de inteiros V=[1 2 3] e armazene o resultado da soma dos seus trs elementos na posio de memria cujo endereo o primeiro endereo aps o fim do vetor. 6- Explique o que acontece no programa do exemplo 3. 7- Escreva um programa em Assembly que receba da consola um nmero inteiro, multiplique esse nmero por 4 (utilizando um operador de rotao) e escreva o nmero outra vez na consola. 8- Escreva um programa que recebe um valor inteiro digitado pelo usurio e mostre na tela do computador o seu valor negado. Utilize as operaes lgicas para realizar esta operao.

19

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

4
4.1

Condicionais e Laos de Repetio


Introduo

As instrues de condio e laos de repetio tm grande importncia nos programas. Estas instrues permitem que o fluxo do programa seja determinado de acordo com a situao dos dados durante a execuo do programa. A linguagem Assembly no possui qualquer estrutura de controle do fluxo do programa que permita decidir sobre dois ou mais caminhos de execuo distintos. Para implementar uma estrutura deste tipo necessrio avaliar previamente uma condio, simples ou composta. O caminho de execuo que o programa segue depender ento desta avaliao. No MIPS as instrues que permitem avaliao so: slt, slti, sltu, sltiu (set less than). Estas instrues comparam dois valores e seta o registrador destino com o valor um se o primeiro dado for menor que o segundo. Caso isso no seja verdade o registrador destino setado com o valor zero. A letra i nas instrues slti e sltiu vem de immediate e quer dizer que nestas instrues podemos usar valores constantes como um dos parmetros. J a letra u vem de unsigned que significa que a instruo permite apenas constantes com valores positivos. Para implementar em assembly os laos de repetio podemos usar as instrues: beq, bne e j (e suas variaes). A instruo beq (branch if equal) possui como parmetro dois registradores e uma constante (endereo do salto). Esta instruo desvia para o endereo de salto caso os dois registradores possuam o mesmo valor. A instruo bne faz exatamente o contrrio da instruo beq. No assembly do MIPS existe uma instruo chamada j (jump) que realiza um salto incondicional para o endereo especificado na instruo. Com estas trs instrues (e suas variaes) podemos implementar diversos tipos de laos de repetio e estruturas de condio. 4.2 Exemplos

Para entendermos melhor como estas instrues funcionam considere o programa abaixo: Exemplo 1: Crie um arquivo com o cdigo do programa abaixo.
msg: .data # Data declaration section .asciiz "Valor de t2: " .text # Start of code section

main:

20

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores
addi $t0,$0,10 addi $t1,$0,11 slt $t2,$t0,$t1 #registrador to recebe o valor 10 #registrador to recebe o valor 10 #se t0<t1 entao t2=1 #senao t2=0 #codigo pra imprimir a msg na tela li $v0,4 la $a0,msg syscall #codigo pra imprimir o valor de t2 na tela li $v0,1 add $a0,$t2,$0 syscall

Neste exemplo colocamos o registrador t0 com o valor 10 e o registrador t1 com o valor 11. Ento, usamos a instruo slt para determinar se o valor de t0 menor que o do t1. Caso seja, o valor armazenado em t2 um. Seno, significa que o valor armazenado em t2 zero. Portanto, podemos perceber que podemos utilizar a instruo slt (e suas variaes) sempre que precisarmos trabalhar com os operadores de relao (< e >=). Exemplo 2: Crie um arquivo com o cdigo do programa abaixo.
.data var1: .word 30 var2: .word 40 res: .space 1 .text main: lw $t0,var1($0) # carrega var1 em t0 lw $t1,var2($0) # carrega var2 em t1 slt $t2,$t0,$t1 # coloca t2 a 1 se t0<t1 sb $t2,res($0) # armazena t2 em res # armazena na memria uma palavra com o valor 30 # armazena na memria uma palavra com o valor 40 # reserva espao na memria para um byte

Neste programa usamos novamente a instruo slt para verificar a relao < entre dois valores. A principal diferena deste programa para o exemplo um que os resultados e os valores esto todos na memria. Neste caso, antes de utilizarmos a instruo slt precisamos trazer da memria os dois valores. Depois o resultado da operao armazenado no byte reservado pela diretiva .space indicada por res. Exemplo 3: Crie um arquivo com o cdigo do programa abaixo.
# # # # # # # # # # Neste exemplo vamos fazer uma estrutura de condicao do tipo if/else. O cdigo C equivalente ao codigo assembly apresentado abaixo : c = 0 d = 2 if(c==d) printf("As variveis c e d possuem o mesmo valor!"); else printf("As variveis c e d so diferentes!");

21

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

.data # Data declaration section msgI: .asciiz "As variveis c e d possuem o mesmo valor!" msgD: .asciiz "As variveis c e d so diferentes!" .text # Start of code section # atribuindo os valores 0 e 2 li $t0,0 li $t1,2 #fazendo a comparao bne $t0,$t1,ElSE #imprimindo o IF li $v0,4 la $a0,msgI syscall #Saindo do IF j FIM ElSE:#imprimindo o ELSE li $v0,4 la $a0,msgD syscall #Saindo do ELSE FIM: main:

No programa listado acima a instruo bne foi utilizada para fazer a estrutura de condio if-else. Podemos perceber que alm da instruo bne tivemos que utilizar a instruo j. Com esta instruo torna-se possvel realizar um jump incondicional para terminar o programa. Exemplo 4: Crie um arquivo com o cdigo do programa abaixo.
# # # # # # # # # # Neste exemplo vamos fazer uma estrutura de condicao do tipo if/else. O cdigo C equivalente ao codigo assembly apresentado abaixo : c = 0 d = 2 if(c>=d) printf("c e maior ou igual a d!"); else printf("c menor que d!");

.data # Data declaration section msgI: .asciiz "c e maior ou igual a d!" msgD: .asciiz "c menor que d!" .text main: # Start of code section # atribuindo os valores 0 e 2 li $t0,0

22

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores
li $t1,2 #fazendo a comparao slt $t2,$t1,$t0 li $t3,1 bne $t2,$t3,ElSE #imprimindo o IF li $v0,4 la $a0,msgI syscall #Saindo do IF j FIM ElSE:#imprimindo o ELSE li $v0,4 la $a0,msgD syscall #Saindo do ELSE FIM:

Neste exemplo usamos a instruo slt em conjunto com a instruo bne. Neste caso tivemos que utilizar a instruo slt porque o bne ou beq s verificam a diferena ou a igualdade de contedos. Neste caso, o programa exigia que fosse realizada a operao relacional >=. Quando encontramos programas como estes devemos sempre usar instruo slt em conjunto com beq ou bne. Exemplo 5: Crie um arquivo com o cdigo do programa abaixo.
# # # # # # # # # # Neste exemplo vamos fazer um lao de repetio do tipo while. O cdigo C equivalente ao codigo assembly apresentado abaixo : c = 0 d = 4 while(c<d){ printf("c menor que d!"); c++; }

.data # Data declaration section msg: .asciiz "c menor que d!" .text # Start of code section # atribuindo os valores 0 e 2 li $t0,0 li $t1,4 #fazendo a comparao WHILE: slt $t2,$t0,$t1 li $t3,1 bne $t2,$t3,FIM #imprimindo a msg li $v0,4 la $a0,msg main:

23

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores
syscall #fazendo o incremento de c addi $t0,$t0,1 j WHILE FIM: # END OF PROGRAM

Neste programa implementamos um lao de repetio do tipo while. Neste caso devemos combinar instrues de salto condicionais com instrues de salto incondicionais. Lembrando sempre de utilizar os rtulos para indicao de linha do salto. Exemplo 6: Crie um arquivo com o cdigo do programa abaixo.
# Um exemplo de controle de fluxo (if-else) # void main(){ # int var1, var2, res; # var1=40; var2=30; res=0; # # se (var2 != 0) # res = var1/var2; # # res = var1+var2+res # } .data var1: .word 40 var2: .word 30 msg: .asciiz "\nValor:" res: .space 4 .text main: lw $t0,var1($0) # carrega var1 em t0 lw $t1,var2($0) # carrega var2 em t1 #mosntrando msg li $v0,4 la $a0,msg syscall # mostrar os valores de var1 li $v0,1 add $a0,$t0,$0 syscall #mosntrando msg li $v0,4 la $a0,msg syscall # mostrar os valores de var1 li $v0,1 add $a0,$t1,$0 syscall #realizando os calculos

24

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores
and $t2,$t2,$0 # t2 = 0 beq $t1,$0,fimse # se t1 = 0, salta para fim do se div $t0,$t1 # var1/var2 e armazena em LO(quociente)e HI (resto) mflo $t2 # armazenar o registrador LO em $t2 fimse: add $t3,$t0,$t1 # t3 = t0 + t1 add $t2,$t3,$t2 # t2 = t3 + t2 sw $t2,res($0) # guardar t2 em res #mosntrando msg li $v0,4 la $a0,msg syscall # mostrar os valores de res li $v0,1 add $a0,$t2,$0 syscall se:

Exemplo 7: Crie um arquivo com o cdigo do programa abaixo.


.data cadeia: .asciiz "AULA_DE_AC" .align 2 n: .space 4 .text main:la $t0,cadeia # carrega endereo da cadeia em t0 andi $t2,$t2,0 # t2 <- 0 enquanto: lb $t1,0($t0) # carrega o byte apontado por t0 em t1 beq $t1,$0,fim # se t1 = 0, saltar para fim addi $t2,$t2,1 # t2 <- t2 + 1 addi $t0,$t0,1 # t0 <- t0 + 1 j enquanto fim: sw $t2,n($0) li $v0,1 add $a0,$t2,$0 syscall

Este programa conta o nmero de letras de uma palavra e exibe na tela. 4.3 Atividades Propostas 1. Modifique o exemplo um para que o valor armazenado em t2 seja zero. 2. Modifique o exemplo dois para que o contedo do registrador t2 seja apresentado na tela do monitor. 3. Crie um programa que permita a entrada de um vetor de inteiros de cinco posies. Este programa dever ser capaz de determinar qual o menor valor dentro do vetor de inteiros. O menor valor deve ser impresso na tela do monitor. 4. Modifique o exemplo trs para que ele utilize a instruo de comparao beq.

25

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores 5. Um rob recebe como entrada (atravs de um sensor) uma imagem representada por um vetor de inteiros de 10 posies (deve ser preenchido aleatoriamente). Cada posio do vetor representa um objeto na imagem. O rob deve marcar apenas as imagens de CDs (so representadas pelo valor inteiro 5). Desta forma implemente um programa que marque ( com o valor zero) as posies do vetor onde temos um CD. 6. Implemente um programa que simule um lao de repetio do tipo for. 7. Modifique o programa do exemplo 4 para que a comparao efetuada seja c > d. 8. Escreva um programa em Assembly do MIPS R2000 que escreva a seguinte mensagem na tela: Introduza um inteiro: > E em seguida leia o inteiro para uma posio de memria rotulada por inteiro. O programa dever ento verificar se o valor introduzido menor do que 1000. Se for, o programa imprime o resultado da multiplicao do inteiro lido por 200, seguido da mensagem fim. Se no for, o programa exibe a seguinte mensagem de erro e termina: Introduziu um inteiro maior que 1000. 9. Crie um programa que implemente o seguinte trecho de cdigo em C: if (var1 == var2) { var1 = var3; /* trocar os valores de var1 e var2 para o valor de var3 */ var2 = var3; } else { tmp = var1; /* executar quando var1 != var2 */ var1 = var2; /* trocar os valores de var1 e var2 */ var2 = tmp;} As variveis var1, var2,var3 devem ser alocadas na memria com os valores iniciais 10, 11 e 12. A varivel tmp pode ser relacionada com o registrador $t0.

26

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

5
5.1

Procedimentos e Funes
Introduo

Um programa desenvolvido em assembly pode ser simplificado se for subdividido em um ou mais sub-problemas, seguindo a abordagem de dividir para conquistar. Neste captulo, iremos aprender o mecanismo de chamada de procedimentos/ funes do MIPS. As funes e os procedimentos permitem escrever um programa complexo de uma forma modular, permitindo assim uma melhor depurao de erros e tambm a reutilizao de subrotinas ao longo de todo o programa. Quando um procedimento (o caller-chamador) chama outro procedimento (o callee-chamado), o controle do programa transferido do caller para o callee, isto , o controle transferido do procedimento que chama para o procedimento chamado. As instrues que tornam possvel isso possvel no MIPS so as instrues jal e jr. Os quatro passos necessrios para executar um procedimento/funo so: 1. Guardar o endereo de retorno. O endereo de retorno o endereo da instruo que surge imediatamente aps o ponto da chamada. 2. Chamar o procedimento. 3. Executar o procedimento. 4. Recuperar o endereo de retorno e retornar ao ponto inicial (que o ponto da chamada). A arquitetura do MIPS fornece duas instrues que so utilizadas em conjunto para realizar a chamada e retornar:
CHAMADA:

jal nome_do_procedimento Esta instruo guarda no registrador $ra o endereo da instruo que surge imediatamente aps o jal (endereo de retorno) e salta para o procedimento especificado pelo rtulo usado na instruo jal. RETORNO: jr $ra Esta instruo salta para o endereo armazenado no registrador $ra. A instruo jr tambm pode ser utilizada com outros registradores e no necessrio que seja usada apenas para a implementao de retorno do procedimento. importante ressaltar que devemos sempre guardar o endereo de retorno do procedimento. Se no o fizermos em $ra podemos fazer um dos registradores salvos ou na pilha. Os registradores salvos so aqueles que so preservados na chamada de um procedimento (olhar tabela 3 captulo 1). E a pilha o que ? A pilha uma parte da

27

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores memria principal (RAM) que responsvel por alocar os dados criados dinamicamente. Quando temos apenas procedimentos folha (procedimentos que no chamam outros procedimentos) no precisamos usar a pilha. Isto acontece porque neste caso precisamos apenas armazenar o endereo de retorno para o procedimento e isso pode ser feito pelo registrador $ra. Entretanto, quando temos procedimentos que chamam outros procedimentos devemos usar a pilha. Mas por qu? J vimos que quando a instruo jal executada ela armazena no registrador $ra o endereo de retorno, mas se temos uma nova chamada (nova execuo do jal) de procedimento um novo endereo de retorno ser armazenado no $ra. Mas, e o $ra anterior? Neste caso, antes de realizarmos um novo jal devemos guardar o valor de $ra na pilha, para que seu vlaor no seja sobrescrito. O nmero de chamadas consecutivas no tem limite (procedimentos podem chamar outros procedimentos que tambm chamam procedimentos etc.). Ento, no podemos utilizar uma localizao fixa (seja ela um registrador ou uma posio de memria) para guardar o registrador $ra. Em vez disso, necessitamos de uma estrutura dinmica, qualquer coisa que nos permita armazenar dados, mas sem escrever por cima de dados previamente guardados. Esta estrutura de dados a pilha (stack) que tem sempre em seu topo o ltimo elemento armazenado. Na arquitetura do MIPS uma pilha cujo topo comea por ter um valor elevado (0x7fff ffff) na memria principal e que cresce para baixo, isto , sempre que se coloca alguma coisa na pilha operao designada por push o endereo do topo da pilha decresce. O registrador $sp (stack pointer) aponta sempre para o topo da pilha, isto , para a primeira posio vazia na pilha. Para utilizar a pilha usamos as instrues de load e store. Alm disso, precisamos do registrador $sp para enderear a pilha. Por exemplo, para guardar o valor de um registrador na pilha, fazemos: add $sp,$sp,-4 # atualizar o stack pointer sw $ra, 4($sp) # push do $ra para o stack A figura abaixo apresenta a pilha antes e depois do armazenamento do $ra na memria.

28

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

Figura 1 Memria antes e depois de realizar o sw na pilha No exemplo acima, subtramos a quantidade correta ao endereo do stack pointer, uma vez que a pilha vai aumentando para baixo (na memria principal). Neste exemplo subtrai- se 4 porque queremos guardar uma palavra (4 bytes) que est no registrador $ra. Depois fazemos o armazenamento (store) usando um deslocamento positivo: 4($sp) significa o endereo contido em $sp + 4, a fim de apontarmos para a posio de memria vazia para onde o $sp apontava antes de o modificarmos. Esta operao designa-se por push. J sabemos como armazenar valores na pilha, mas como retiramos os valores armazenados da pilha? Para isso usamos a instruo load (pop) e usamos o registrador $sp como registrador base. No exemplo anterior o cdigo seria: lw $ra,4($sp) # recupera-se o dado da pilha add $sp,$sp,4 # atualiza o $sp importante ressaltar que todo o controle do stack pointer e dos dados armazenados na pilha fica por conta do programador. Portanto, muito cuidado ao trabalho com a pilha de dados. Passagem de Parmetros: Existem duas formas de passar parmetros a um procedimento: pelos registradores e pela pilha. A conveno do MIPS especifica que os 4 primeiros argumentos de um procedimento so passados por registradores ($a0-$a3). Os demais so passados pela pilha. Se o procedimento chamar outros procedimentos, ento os registradores de argumentos devem ser armazenados nos registradores salvos ou na pilha. Chamando um Procedimento: O caller realiza o seguinte antes operaes antes de chamar outro procedimento:

29

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores 1. Guarda registradores que no so preservados nas chamadas ($a0-$a3 e $t0-$t9) que sero usados aps a realizao da chamada. 2. Passa os parmetros: os 4 primeiros so passados em $a0-$a3, os restantes so passados pela pilha. 3. Salta para o procedimento usando a instruo jal. 4. Aps a chamada, ajusta o $sp. O callee (procedimento chamado) faz o seguinte: 1. Guarda o $ra se o procedimento for chamar outro procedimento. 2. Guarda quaisquer registradores $s0-$s7 que o procedimento modifique. 3. Realiza o que tem que realizar. 4. No caso de retornar um valor, coloca esse valor no registrador $v0 ou $v1. 5. Restaura todos os registradores previamente guardados (pop da pilha). 6. Retorna, executando jr $ra. 5.2 Exemplos

Nesta seo apresentamos alguns exemplos de programas que possuem procedimentos/funes. Alm disso, apresentamos programas que usam a pilha como memria auxiliar para armazenar os dados referentes ao programa. Exemplo 1: Crie um arquivo com o cdigo do programa abaixo.
.data str1: .asciiz "origem " str2: .asciiz "copia " msg: .asciiz "PROGRAMA COPIA PALAVRA: str2<-str1\n" ql: .asciiz "\n" msg1: .asciiz "\nNovo valor de str2=" .text main:
addi $sp, $sp, -4 # reserva uma posio no stack sw $ra, 0($sp) # guarda o endereo de retorno

#imprimindo li $v0,4 la $a0,msg syscall #imprimindo li $v0,4 la $a0,str1 syscall #imprimindo li $v0,4 la $a0,ql syscall #imprimindo li $v0,4 la $a0,str2 syscall jal strcpy

msg inicial na tela

str1 na tela

str2 na tela

str2 na tela

#fazendo a chamada de procedimento

30

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores
#imprimindo str2 na tela li $v0,4 la $a0,msg1 syscall #imprimindo str2 na tela li $v0,4 la $a0,str2 syscall
end: lw $ra, 0($sp) # recupera endereo de retorno addi $sp, $sp, 4 # pop do stack pointer jr $ra

strcpy: add $s0, $0, $0 # $s0 = i = 0 la $t5, str1 # guarda endereo de str1 em $t5 la $t6, str2 # guarda endereo de str2 em $t6 L1: add $t1, $s0, $t5 # carrega em $t1 endereo de str1 que o y(i) lb $t2, 0($t1) # carrega o byte y(i) em $t2 add $t3, $s0, $t6 # carrega em $t3 endereo de str2 que o x(i) sb $t2, 0($t3) # armazena em x(i) o byte y(i) que est em $t2 addi $s0, $s0, 1 # incremento de 1 (byte seguinte) bne $t2, $0, L1 # se y(i) != 0 ento continua a copiar jr $ra

O programa acima possui duas variveis var1 e var2. O programa copia o contedo da var1 para a var2 e exibe o novo valor de var2. Este programa possui um procedimento chamado strcpy e ele o responsvel por copiar o valor de uma varivel para a outra. Para realizar esta chamada o programa principal utiliza a instruo JAL e no procedimento a instruo jr para retornar ao programa principal. Neste programa a pilha foi usada para armazenar o endereo de retorno do main (tambm um procedimento). Exemplo 2: Crie um arquivo com o cdigo do programa abaixo.
# # # # # # # # # # # # # # # # # # # O programa em assembly representa este cdigo em C: int soma(int x, int y, int z) { return (x+y+z); } void main() { int a, b, c, s; a = b = c = s = 0 ; cin>>a; cin>>b; cin>>c; s = soma(a,b,c); cout<<"SOMA="<<s;

31

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores
# } .data # Data declaration section msg: .asciiz "\nSOMA="; msgA: .asciiz "\nDigite o valor de a="; msgB: .asciiz "\nDigite o valor de b="; msgC: .asciiz "\nDigite o valor de c="; .text main: # Start of code section # armazenando ra do main na pilha addi $sp,$sp,-4 sw $ra,4($sp) #pegando os valores do teclado para a varivel a li $v0,4 la $a0,msgA syscall li $v0,5 syscall add $s0,$v0,$0 # salvando o valor lido em s0 (a) #pegando os valores do teclado para a varivel b li $v0,4 la $a0,msgB syscall li $v0,5 syscall add $s1,$v0,$0 # salvando o valor lido em s1 (b) #pegando os valores do teclado para a varivel c li $v0,4 la $a0,msgC syscall li $v0,5 syscall add $s2,$v0,$0 # salvando o valor lido em s2 (c) #armazenar os argumentos addi $a0,$s0,0 addi $a1,$s1,0 addi $a2,$s2,0 #chamar a funo jal soma addi $t0,$v0,0 #Imprimindo a resposta li $v0,4 la $a0,msg syscall li $v0,1 add $a0,$t0,$0 syscall lw $ra,4($sp) addi $sp,$sp,4 jr $ra

end:

#funcao soma

32

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores
soma: add $v0,$a0,$a1 add $v0,$v0,$a2 jr $ra

5.3

Atividades Propostas 1- Converta o programa em C que utiliza procedimentos para a linguagem assembly do MIPS. Para isso utilizaremos uma nova instruo chama rem $s0,$s1,$s2, que retorna o resto da diviso entre $s1 e $s2 em $s0. Considere que as variveis esto nos seguintes registradores: $s0 = N; $s1 = C.

int Par (int Numero) { if(Numero%2 == 0) return 1; else return 0; } void main(void) { int N = 64; int C = 0; do { if(Par(N) == 0) C++; N--; } while(N > 0); } 2- Converta o programa em C que utiliza procedimentos para a linguagem assembly do MIPS. Considere que o vetor A est na memria (armazene ele na memria) e que possui os valore 15,13,17 e 18 respectivamente. As variveis esto nos seguintes registradores: $s0 = N e $s1 = Media. int Dividir(int X, int Y) { return(X/Y); } int Calcula_Media(int A[], int N) { int I; int Soma = 0; for(I = 0; I < N; I++) { Soma = Soma + A[I]; } Soma = Dividir(Soma,N); return(Soma);

33

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores } void main(void) { int N = 4; int Media; int A[4]; Media = Calcula_Media(A,N); }

34

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

6
6.1

Entrada e Sada Consulta de Estado


Introduo

Os computadores sempre tm que se relacionar com o mundo exterior. Neste caso este relacionamento realizado atravs dos perifricos: teclado, impressora, monitor, etc. Os perifricos comunicam com o computador por meio de um sistema, chamado sistema de entrada/sada. No computador o elemento que permite essa comunicao chamado de interface. A interface constituda por um circuito, chamado controlador ou dispositivo de E/S. Estas interfaces e controladores so especficas para cada perifrico e o computador comunica com elas a fim de program-los e comunicar com os perifricos, lendo e escrevendo em endereos chamados de portas. Quando os endereos destas portas correspondem a endereos de memria do computador, para ler ou escrever nestas portas utiliza-se as mesmas instrues que lem/escrevem da memria. Neste caso diz-se que o sistema de E/S se encontra mapeado na memria. este o sistema utilizado no caso do processador MIPS. Se, por outro lado, se utilizam instrues especiais, diz-se que o computador possui um mapa de endereos de E/S independente (caso da Intel). Neste captulo abordamos a forma mais simples de interagir com os perifricos. Essa forma designa-se por consulta de estado. Os perifricos que vamos usar so o teclado (entrada) e a consola (sada). A tcnica de consulta de estado pressupe que o controlador do dispositivo possua uma porta de leitura/escrita de dados e pelo menos uma porta de controle. A leitura, por parte do processador, da porta de controle, e em particular de um bit chamado bit de estado, indica se o controlador est pronto para ler ou escrever dados atravs do perifrico mediante a porta de leitura/escrita de dados. No SPIM, para a entrada de dados a partir do teclado, utiliza-se a porta de dados cujo endereo o 0xffff0004. A porta de controle situa-se no endereo 0xffff0000 (sendo o bit 0 o bit de estado, o qual indica que o controlador possui um caractere digitado no teclado. Para a sada de dados para o console, a porta de dados o endereo 0xffff000c e a porta de controle o endereo 0xffff0008 (sendo o bit 0 o bit de estado que indica que se pode escrever um caractere). 6.2 Exemplos

Nesta seo apresentamos alguns exemplos de programas que possuem entrada/sada por consulta de estado. Exemplo 1: Crie um arquivo com o cdigo do programa abaixo.

35

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

.data 0x10010000 long: .word 7 # dimenso do buffer buffer: .space 7 # buffer onde se armazenam os caracteres teclados .data 0xffff0000 cin: .space 1 # porta de controle do teclado .data 0xffff0004 in: .space 1 # porta de leitura do teclado .text .globl main main: la $a0, buffer # carrega o endereo do buffer lw $v0,long($0) # controle do tamanho do buffer addi $v0,$v0,-1 li $v1,0x0a # caracter return, muda de linha (\n) la $a1, in # carrega endereo in la $a2, cin # carrega endereo de controle do teclado ctr: lb $t0, 0($a2) andi $t0,$t0,1 beq $t0,$0, ctr lb $s0, 0($a1) # l da porta do teclado sb $s0,0($a0) # armazena o dado no buffer addi $a0,$a0,1 # incrementa apontador do buffer addi $v0,$v0,-1 # decr. tamanho restante buffer bne $v0,$0, ctr # controle de fim de string li $s0, 0x00 sb $s0,0($a0) # armazena fim de string no buffer jr $ra # retorna ao main

fim:

Este programa espera por l seis caracteres do teclado e armazena no endereo de memria referenciado por buffer. A leitura de caracteres realizada atravs de consulta de estado do bit 0 da porta de controle da entrada. Exemplo 2: Crie um arquivo com o cdigo do programa abaixo.
.data 0x10010000 cadeia: .asciiz "Sada por consulta de estado!!"

.data 0xffff0008 print: .space 1 # Porto de controlo da consola .data 0xffff000c out: .space 1 # Porto de escrita da consola .text

36

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores
.globl main main: la $a0,cadeia # carrega endereo da cadeia la $a1,out # carrega endereo de sada lb $s0,0($a0) # l o caracter (byte) da cadeia la $a2,print # carrega endereo de controlo da sada ############# ciclo de consulta de estado ########## ctr1: ############### ciclo de atraso ############## li $t0,n # n deve ser substitudo por um valor cont: addi $t0,$t0,-1 bnez $t0,cont ############################################### #################################################### sb $s0, 0($a1) # escreve no console addi $a0,$a0,1 # incrementa apontador para a cadeia lb $s0, 0($a0) # l o caractere (byte) seguinte bne $s0,$0,ctr1 # controle de fim de cadeia (0) ############ ciclo de consulta de estado ########## ctr2: ############### ciclo de atraso ############## li $t0,n # n deve ser substitudo por um valor cont1:addi $t0,$t0,-1 bnez $t0,cont1 ############################################### #################################################### sb $0, 0($a1) # escreve no console fim de cadeia (0) jr $ra # regressa rotina principal

Exemplo 3: Crie um arquivo com o cdigo do programa abaixo.


.data 0xffff0000 cin: .space 1 .data 0xffff0004 in: .space 1 .data 0xffff0008 cout: .space 1 .data 0xffff000c out: .space 1 .text main: addi $sp,$sp,-4 sw $ra,0($sp) lw $s0,long addi $s0,$s0,-1 li la la la $t6,0x0a # return $t1, in # carrega endereo in $t2, cin # carrega endereo de controle do teclado $t3, out # carrega endereo out

37

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores
la $t4, cout # carrega endereo de controle da sada ctri: ci:

lb $t0, 0($t2) andi $t0,$t0,1 beq $t0,$0, ci lb $t7, 0($t1) # leio do teclado ############### ciclo de atraso ############## li $t0,10 # n deve ser substitudo por um valor cont: addi $t0,$t0,-1 bnez $t0,cont ############################################### sb $t7, 0($t3) # escrevo no console addi $s0,$s0,-1 beq $t7,$t6, fim # controle fim de linha bne $s0,$0, ctri # controle de fim de cadeia j zero fim: li $t7, 0x0a addi $a1,$t4,0 ############### ciclo de atraso ############## li $t0,10 # n deve ser substitudo por um valor cont1: addi $t0,$t0,-1 bnez $t0,cont1 ############################################### sb $t7, 0($t3) # escrevo no console zero: andi $t7,$t7,0 addi $a1,$t4,0 ############### ciclo de atraso ############## li $t0,10 # n deve ser substitudo por um valor cont2: addi $t0,$t0,-1 bnez $t0,cont2 ############################################### sb $t7, 0($t3) # escrevo no console lw $ra, 0($sp) addi $sp,$sp,4 jr $ra

6.3

Atividades Propostas 1- Explique o exemplo dois. 2- Explique o exemplo trs.

38

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

7
7.1

Entrada e Sada Interrupo


Introduo

Neste captulo iremos conhecer o mecanismo de excees do processador MIPS e no fim deste captulo seremos capazes de escrever cdigo de tratamento de excees (exception handlers) para o MIPS. Os saltos condicionais (branches) e incondicionais (jumps) constituem uma forma de alterar o controle de fluxo de um programa. As excees tambm so uma maneira de alterar o controle de fluxo de um programa em Assembly. A conveno do MIPS considera como uma exceo toda e qualquer alterao inesperada no controle do fluxo de um programa, independentemente da sua origem (i. , no h distino entre uma fonte externa ou uma fonte do prprio processador). Uma exceo sncrona se ocorrer no mesmo lugar toda vez que um programa executado com os mesmos dados e com a mesma alocao de memria. Os overflows aritmticos, instrues no definidas, page faults, so exemplos de excees sncronas. As excees assncronas, por outro lado, ocorrem sem qualquer relao temporal com o programa que executado. Pedidos de E/S, erros de memria, falhas de fornecimento de energia etc. so exemplos de excees assncronas. Uma interrupo uma exceo assncrona. As excees sncronas, que resultam diretamente da execuo do programa, so designadas por traps. Quando uma exceo ocorre, o controle transferido para um programa diferente, chamado exception handler (rotina de tratamento da exceo), escrito para lidar com as excees. Aps a exceo, o controle devolvido ao programa principal no ponto em que ocorreu a exceo: esse programa continua como se nada tivesse acontecido. Uma exceo como uma rotina (sem parmetros e sem valor de retorno). Uma vez que o cdigo de tratamento da exceo pode ser executado a qualquer altura, no pode haver passagem de parmetros para esse cdigo: tal passagem requer uma preparao prvia. Pela mesma razo no pode haver retorno de valores. importante ter em conta que o exception handler tem de preservar o estado do programa que foi interrompido de modo a que a sua execuo possa prosseguir mais tarde. Tal como acontece com qualquer outro procedimento, o exception handler tem de guardar quaisquer registradores que possam modificar, restaurando o seu valor antes de devolver o controle ao programa interrompido. Guardar os registradores na memria um problema no MIPS: enderear a memria requer um registrador base. Isto significa que um registrador tem de ser modificado antes que qualquer registrador possa ser guardado! A conveno de utilizao dos registradores no MIPS (ver Tabela do Manual) reserva os registradores $26 e $27 ($k0 e $k1) para utilizao por parte do interrupt handler.

39

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores Isto significa que o interrupt handler pode usar estes registradores sem primeiro ter que salva-los. Um programa escrito para o MIPS que use estes registradores pode encontr-los subitamente alterados. O mecanismo de excees do MIPS O mecanismo de excees implementado no coprocessador 0, que est sempre presente no MIPS (ao contrrio do coprocessador 1, que pode ou no estar presente). O sistema de memria virtual tambm implementado no coprocessador 0. Note, contudo, que o SPIM no simula esta parte do processador. A CPU opera em dois modos possveis: user e kernel. Os programas do usurio rodam no modo user. A CPU entra no modo kernel quando ocorre uma exceo. O Coprocessador 0 s pode ser utilizado no modo kernel. Toda a metade superior do espao de memria reservada para o modo kernel: no pode, por isso, ser usado no modo usurio. Ao rodar no modo kernel, os registradores do coprocessador 0 podem ser usados com as seguintes instrues: Instruo Comentrio mfc0 Rdest, C0src Move o contedo do registrador do Coprocessador 0 C0src para o registrador destino Rdest. mtc0 Rsrc, C0dest O registrador de inteiros Rsrc movido para o registrador C0dest do Coprocessador 0. lwc0 C0dest, address Carrega uma palavra a partir do endereo address para o registrador C0dest. swc0 C0src, address Armazena o contedo do registrador C0src no endereo address da memria. Os registrador do coprocessador 0 relevantes para o tratamento das excees no MIPS so: N do Registo Nome Utilizao 8 BadVAddr Endereo de memria onde ocorreu a exceo. 12 Status Mscara da interrupo, bits enable e status na altura da interrupo. 13 Cause Tipo de exceo e bits de interrupes pendentes. 14 EPC Endereo da instruo que causou a interrupo. O registrador BadVAddr

40

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores Este registrador, cujo nome vem de Bad Virtual Address, contm o endereo de memria onde ocorreu a exceo. Um acesso desalinhado memria, por exemplo, ir gerar uma exceo e o endereo acessador ser guardado em BadVAddr. O registrador Cause O registrador Cause fornece informao sobre quais as interrupes pendentes (bits 10 a 15) e a causa da exceo. O cdigo da exceo armazenado como um inteiro sem sinal usando os bits 5-2 no registrador Cause. A figura seguinte representa este registrador:

O bit i do grupo de bits Pending Interrupts fica a 1 se uma interrupo ocorre no nvel i e est pendente (diz-se que ainda no foi resolvida). O cdigo da exceo indica o que causou a exceo: Cdigo Nome Descrio 0 INT Interrupo. 4 ADDRL Load a partir de um endereo ilegal. 5 ADDRS Store para um endereo ilegal. 6 IBUS Erro do bus ao efectuar fetch de uma instruo. 7 DBUS Erro do bus numa referncia a dados. 8 SYSCALL Instruo syscall executada. 9 BKPT Instruo break executada. 10 RI Instruo reservada. 12 OVF Overflow aritmtico. O cdigo 0 indica que uma interrupo ocorreu. Olhando para os bits Pending Interrupts individuais, o processador pode saber que interrupo especfica que ocorreu. O registrador Status O registrador Status contm uma mscara de interrupes nos bits 5-10 e informao de estado nos bits 5-0. O esquema do registrador o seguinte:

41

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

Se o bit Interrupt mask i estiver a 1, ento as interrupes do nvel i esto ativas (enabled). Caso contrrio esto inativas (disabled). O bit 1 no registrador indica se o programa roda no modo usurio (=1) ou kernel (=0). O bit 3, indica se o processador rodava no modo kernel (=0) ou usurio quando ocorreu a ltima exceo. Esta informao importante porque ao retornar do exception handler, o processador tem que estar no mesmo estado em que estava antes de ocorrer a exceo. Os bits 5-0 no registrador Status implementam uma pilha de trs nveis com informao sobre de excees anteriores. Quando uma exceo ocorre, o estado previous (bits 3 e 2) guardado como o estado old e o estado current guardado como estado previous. O estado old perdido. Os bits do estado current so ambos colocados em zero (modo kernel com interrupes inativas). Ao retornar do exception handler (executando uma instruo que j veremos, designada por rfe) o estado previous torna-se o estado current e o estado old torna-se em previous. O estado old no alterado. Os bits de ativao de interrupes (Interrupt Enable), indicam se as interrupes esto ativas (ou habilitadas, ou permitidas), caso em que esto a 1, ou inativas, caso em que esto a 0, no respectivo estado. Por exemplo, se o bit 0 zero, ento o processador est a correr atualmente com as interrupes inativas. O registrador EPC Quando um procedimento chamado usando jal, duas coisas acontecem: - O controle transferido para o endereo fornecido pela instruo. - O endereo de retorno guardado no registrador $ra. No caso de uma exceo, no h uma chamada explcita. No MIPS, o controle transferido para uma localizao fixa, 0x80000080, quando uma exceo ocorre. O exception handler tem de ficar nesse endereo. O endereo de retorno no pode ser salvo em $ra, uma vez que pode escrever por cima de um endereo de retorno que tenha eventualmente sido colocado nesse registrador antes da exceo. O registrador EPC (Exception Program Counter) usado para armazenar o endereo da instruo que estava sendo executada quando a exceo foi gerada. Retornar de uma exceo 42

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

A seqncia de retorno standard: # # the return sequence from the exception handler for the case of an # external exception (interrupt) # mfc0 $k0, $14 # get EPC in $k0 rfe # return from exception jr $k0 # replace PC with the return address A arquitetura estabelece uma distino clara entre interrupes (excees externas) e traps (incluindo invocaes explcitas por software, como o syscall). No caso de uma interrupo, o Program Counter avanado para apontar para a prxima instruo no momento em que o controle foi transferido para o exception handler. Por outras palavras, o EPC contm o endereo da instruo que ser executada aps o retorno do exception handler. No caso de um trap ou syscall, o EPC contm o endereo da instruo que gerou o trap. Para evitar executar a instruo outra vez ao retornar do exception handler, o endereo de retorno tem de ser incrementado por 4. Assim, assegura-se que a instruo que se segue no fluxo do programa ser executada. # the return sequence from the exception handler for the case of a # trap (including a syscall). # mfc0 $k0, $14 # get EPC in $k0 addiu $k0, 4 # make sure it points to next instruction rfe # return from exception jr $k0 # replace PC with the return address Compreendendo um Exception Handler Resumindo, quando se gera uma exceo, o processador leva executa as seguintes aes: 1. Armazena o endereo da instruo que gerou a exceo no registrador EPC. 2. Armazena o cdigo da exceo produzida no registrador Cause. Quando se trata de uma interrupo, ativa o bit que indica o nvel do pedido. 3. Salvaguarda o registrador Status no prprio registrador de Status, deslocando a informao dos 6 primeiros bits 2 posies para a esquerda, e coloca os dois primeiros bits a 0, indicando que se passou para o modo kernel e que as interrupes esto mascaradas. 4. Carrega no Program Counter um endereo de memria fixo (0x80000080 no espao de endereamento do kernel). Este o endereo a partir do qual est armazenada a rotina de servio geral de tratamento de excees (interrupt handler, que se encontra no ficheiro trap.handler). Esta rotina determina a causa da excepo e salta para o local adequado do Sistema Operacional a fim de tratar a exceo. A rotina de tratamento da 43

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores exceo responde a uma exceo fazendo terminar o programa que a causou ou realizando uma determinada seqncia de aes. Descrio do controlador do teclado simulado pelo SPIM O controlador do teclado que simulado pelo SPIM dispe de dois registradores de controle e de dados. O registrador de controle est no endereo 0xffff0000 e s se usam dois dos seus bits. O bit 0 o bit de estado e j vimos o seu funcionamento no captulo anterior. O bit 1 o bit de permisso de interrupes. Quando est em 1 significa que a interrupo deste dispositivo permitida (est ativa, ou habilitada). A zero no est permitida. Este bit pode ser modificado por um programa. Se este bit estiver em 1, o dispositivo solicitar uma interrupo de nvel 0 ao processador quando o bit de estado tambm estiver em 1. De todos os modos, para que o processador atenda esta interrupo, todas as interrupes devem estar ativas tambm no registrador de estado (Status) do processador (bits 0 e bits de 8 a 1). O registrador de dados localiza-se no endereo 0xffff0004. 7.2 Exemplos

Este programa adaptado do arquivo trap.handler do ncleo do SPIM: .data 0x10010000 perm: .word 0x00000101 caracter: .asciiz "----------------------\n" lido: .word 0 .data 0xffff0000 cin: .space 1 # controle de leitura .data 0xffff0004 in: .space 1 # porta de leitura .data 0xffff0008 cout: .space 1 # controle de escrita .data 0xffff000c out: .space 1 # porta de escrita # Agora vem a zona de dados do Sistema Operacional do MIPS: .kdata inter: .asciiz " int " # mensagem que aparece quando o processador # atende a interrupo __m1_: .asciiz " Exception " __m2_: .asciiz " occurred and ignored\n" __e0_: .asciiz " [Interrupt] " __e1_: .asciiz "" __e2_: .asciiz "" __e3_: .asciiz "" __e4_: .asciiz " [Unaligned address in inst/data fetch] " __e5_: .asciiz " [Unaligned address in store] " __e6_: .asciiz " [Bad address in text read] " __e7_: .asciiz " [Bad address in data/stack read] " __e8_: .asciiz " [Error in syscall] " __e9_: .asciiz " [Breakpoint] "

44

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores
__e10_: .asciiz " [Reserved instruction] " __e11_: .asciiz "" __e12_: .asciiz " [Arithmetic overflow] " __e13_: .asciiz " [Inexact floating point result] " __e14_: .asciiz " [Invalid floating point result] " __e15_: .asciiz " [Divide by 0] " __e16_: .asciiz " [Floating point overflow] " __e17_: .asciiz " [Floating point underflow] " __excp: .word __e0_,__e1_,__e2_,__e3_,__e4_,__e5_,__e6_,__e7_,__e8_,__e9_ .word __e10_,__e11_,__e12_,__e13_,__e14_,__e15_,__e16_,__e17_ s1: .word 0 s2: .word 0 # Rotina do servio geral de excees armazenada no ncleo do S.O. .ktext 0x80000080 .set noat # Because we are running in the kernel, we can use $k0/$k1 without # saving their old values. move $k1 $at # Save $at .set at sw $v0 s1 # Not re-entrent and we can't trust $sp sw $a0 s2 mfc0 $k0 $13 # Ler Registrador Cause e guard-lo em $k0 sgt $v0 $k0 0x44 # Se for uma interrupo externa, salta para a # rotina de tratamento! bgtz $v0 ext addu $0 $0 0 li $v0 4 # syscall 4 (print_str) la $a0 __m1_ syscall li $v0 1 # syscall 1 (print_int) srl $a0 $k0 2 # shift Cause reg syscall li $v0 4 # syscall 4 (print_str) lw $a0 __excp($k0) syscall bne $k0 0x18 ok_pc # Bad PC requires special checks mfc0 $a0, $14 # EPC and $a0, $a0, 0x3 # Is EPC word-aligned? beq $a0, 0, ok_pc li $v0 10 # Exit on really bad PC (out of text) syscall ok_pc: li $v0 4 # syscall 4 (print_str) la $a0 __m2_ syscall mtc0 $0, $13 # Clear Cause register bnez $v0, ret ####################################################################### # # Rotina (nossa) de servio interrupo: ####################################################################### #

45

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores
ext: li $v0 4 la $a0 inter syscall li $v0 1 lb $a0 in syscall sb $a0 lido($0) li $v0 1 lb $a0 lido($0) syscall li $v0,105 # tecla i beq $a0,$v0,ok bne $a0,$v0,continua ok: li $v0 4 la $a0 caracter syscall continua: mtc0 $0, $13 # Limpar o registrador Cause # Retorno do tratamento de uma exceo para a instruo interrompida: ret: lw $v0 s1 lw $a0 s2 mfc0 $k0 $14 # EPC .set noat move $at $k1 # Restore $at .set at rfe # Return from exception handler addiu $k0 $k0 4 # Return to next instruction jr $k0 # Standard startup code. Invoke the routine main with no arguments. .text .globl __start __start: lw $a0, 0($sp) # argc addiu $a1, $sp, 4 # argv addiu $a2, $a1, 4 # envp sll $v0, $a0, 2 addu $a2, $a2, $v0 jal main li $v0 10 syscall # syscall 10 (exit) # cdigo de inicializao necessrio para que a entrada de dados # seja gerida por interrupes: .globl main main: addi $sp,$sp,-4 # ativao das interrupes do teclado lw $t0,cin($0) ori $t0,$t0,2 sw $t0,cin($0) # ativao das interrupes do nvel zero mfc0 $t0,$12 lw $t1,perm($0)

46

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores
or $t0,$t0,$t1 mtc0 $t0,$12 haz: addi $t1,$0,10000 wat: addi $t1,$t1,-1 bnez $t1,wat addi $s0,$s0,1 bnez $s0,haz lw $ra,0($sp) addi $sp,$sp,4 jr $ra O programa anterior inclui, por um lado, o cdigo necessrio para que a entrada de dados se possa gerir perante interrupes e, por outro lado, as aes que devem ser executadas para cada uma das excees que produzidas no sistema.

7.3

Atividades Propostas

1 Explique o programa do exemplo 1

47

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

Referencias Bibliogrficas

[1] MIPS Tecnologies : http://www.mips.com, Empresa MIPS [2] Patterson, D. A., Hennessy, J. L. Organizao e Projeto de Computadores A Interface Hardware/Software, 3a Edio, Editora Campus, 2005. [3] Notas de Estudo Prof. Alberto Jos. http://gec.di.uminho.pt/discip/TextoAC/AnexoD.html [4] Instrues http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html
http://www.ncc.up.pt/~zp/aulas/9899/me/trabalhos/alunos/Processadores/programacao/main.htm

[5] Instrues ponto flutuante

[6] Instrues ponto flutuante http://www.inf.ufrgs.br/~flavio/ensino/cmp237/aula02.pdf

48

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores

Anexo

O SPIM simula um sistema completo, para isso foi includo um simulador de um kernel virtual. Essa parte do simulador executa um conjunto de funes auxiliares, como seja a leitura do teclado e a escrita no monitor de strings e variveis de vrios tipos. Alm das funes bsicas o SPIM possui suporte s interrupes e excees. Exemplos so: mandar imprimir alguma coisa no monitor, capturar dados lidos do teclado, verificar uma diviso por zero, instruo invlida etc. Quanto s funes disponveis no kernel para o programador, elas esto resumidas na tabela abaixo. Para utilizar estas funes, o programador deve guardar no registrador $v0 o valor associado funo que pretende chamar. Alm disso, deve armazenar nos registradores ($a0, $a1 e $f12) os argumentos, quando for necessrio. Depois s chamar a "instruo" syscall. Esta instruo, definida apenas no contexto do simulador, simula a chamada da funo do kernel, executa a respectiva funo e devolve os resultados nos registradores $v0 e $f0.

Cdigo (em $v0) 1 2 4 5 6 7

Funo Escrever um valor inteiro Escrever um valor float Escrever uma string Ler um valor inteiro Ler um valor float Ler um valor double

Argumento(s) $a0 = valor inteiro $f12 = valor float $a0 = ponteiro para a string

Resultado(s) O valor escrito na janela do monitor O valor escrito na janela do monitor O valor escrito na janela do monitor $v0 fica com o valor lido $f0 fica com o valor lido $f0 fica com o valor lido

Ler uma string

$a0 = ponteiro para memria $a1 = nmero mximo de caracteres de $a0 = memria quantidade de

A string lida para a memria

9 10 11

Pedir espao memria

$v0 fica com o endereo inicial da zona de memria

Finalizar programa Escrever um byte $a0 = byte O valor escrito na janela do monitor

Tabela 1 Cdigos para chamadas de sistema

49

Universidade de Itana - Faculdade de Engenharia Engenharia Eletrnica com nfase em Automao e Telecomunicaes Arquitetura de Computadores Outras instrues do MIPS:

50

Вам также может понравиться