# # Autor(s) : Jordi Ferrer Plana # e-mail : jferrerp@eia.udg.es # Branch : - # # Working Group : Departament d'Electrònica, Informàtica i Automàtica # Project : Examen d'ETIS/ETIG d'Estructura i Tecnologia de Computadors, # 2ona convocatòria, any 2006. # Homepage : http://eia.udg.es/etc/ # # Module : Problema 5: BEER | REEB (MIPS). Voltejar Horitzontalment # una Imatge. # # File : voltejarH_print.s # Date : 26/06/2006 - 26/06/2006 # # Compiler : Spim >= 6.3 # Libraries : - # # Notes : - La Imatge es defineix de 38x28 enlloc de 384x288 perquè # es pugui visualitzar el resultat per pantalla. # - A l'enunciat només es demanaven la rutina "principal" i la # rutina "voltejarH". Les rutines "inicialitzar" i "escriure" # són per comprovar que la implementació és correcta. # - En els comentaris s'utilitzen els noms de variables del # codi en C per poder comparar la traducció feta. # # ---------------------------------------------------------------------------- # # Copyright (C) 2004-2005, Jordi Ferrer Plana # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # See the GNU General Public License (http://www.gnu.org/copyleft/) # for more details. # # ---------------------------------------------------------------------------- # .data # Width : .word 384 # Amplada de la Imatge # Height: .word 288 # Altura de la Imatge # Image : .space 442368 # Espai: 384 x 288 * 4 Bytes = 442368 Width : .word 38 # Amplada de la Imatge Height: .word 28 # Altura de la Imatge Image : .space 4256 # Espai: 38 * 28 * 4 Bytes = 4256 Espai : .asciiz " " # Un Espai en Blanc Return: .asciiz "\n" # Un Return .end # # void inicialitzar ( Image : Adreça, Width: Natural, Height : Natural ); # # NOTES: # En conveni MIPS: # Es pot utilitzar $t0 - $t9 dins la funció sense guardar-los. # Els paràmetres estaran a: # $a0: Adreça de la Imatge (Enter sense signe). # $a1: Width (Enter sense signe). # $a2: Height (Enter sense signe). # # No es guardarà res a la pila ja que no cal. # .text inicialitzar: li $t0, 0 # i <- 0 fori1: bge $t0, $a2, exiti1 # Mentre i < Height li $t1, 0 # j <- 0 forj1: bge $t1, $a1, exitj1 # Mentre j < Width mul $t2, $t0, $a1 # $t2 <- i * Width add $t2, $t2, $t1 # $t2 <- i * Width + j sll $t2, $t2, 2 # $t2 <- ( i * Width + j ) * 4 add $t2, $t2, $a0 # $t2 <- Image + ( i * Width + j ) * 4 sw $t1, 0($t2) # Mem[ $t2 ] <- j addi $t1, $t1, 1 # j++ j forj1 # Propera iteració exitj1: addi $t0, $t0, 1 # i++ j fori1 # Propera iteració exiti1: jr $ra # Retornar a l'invocador .end # # void escriure ( Image : Adreça, Width: Natural, Height : Natural ); # # NOTES: # En conveni MIPS: # Es pot utilitzar $t0 - $t9 dins la funció sense guardar-los. # Els paràmetres estaran a: # $a0: Adreça de la Imatge (Enter sense signe). # $a1: Width (Enter sense signe). # $a2: Height (Enter sense signe). # # No es guardarà res a la pila ja que no cal. # .text escriure: move $t3, $a0 # $t3 <- $a0 (Guardar temporalment) li $t0, 0 # i <- 0 fori2: bge $t0, $a2, exiti2 # Mentre i < Height li $t1, 0 # j <- 0 forj2: bge $t1, $a1, exitj2 # Mentre j < Width mul $t2, $t0, $a1 # $t2 <- i * Width add $t2, $t2, $t1 # $t2 <- i * Width + j sll $t2, $t2, 2 # $t2 <- ( i * Width + j ) * 4 add $t2, $t2, $t3 # $t2 <- Image + ( i * Width + j ) * 4 li $v0, 1 # Crida Imprimir Enter lw $a0, 0($t2) # Escriure Mem[ $t2 ] syscall # Escriure a la consola li $v0, 4 # Crida Imprimir Cadena la $a0, Espai # Un espai en blanc syscall # Escriure a la consola addi $t1, $t1, 1 # j++ j forj2 # Propera iteració exitj2: # $v0 ja val 4: Crida Imprimir Cadena la $a0, Return # Un Retorn de Carro syscall # Escriure a la consola addi $t0, $t0, 1 # i++ j fori2 # Propera iteració exiti2: # $v0 ja val 4: Crida Imprimir Cadena # $a0 ja val l'adreça Return syscall # Escriure a consola move $a0, $t3 # Recuperar el valor de $a0 de $t3 jr $ra # Retornar a l'invocador .end .text # # void voltejarH ( Image : Adreça, Width: Natural, Height : Natural ); # # NOTES: # En conveni MIPS: # Es pot utilitzar $t0 - $t9 dins la funció sense guardar-los. # Els paràmetres estaran a: # $a0: Adreça de la Imatge (Enter sense signe). # $a1: Width (Enter sense signe). # $a2: Height (Enter sense signe). # # No es guardarà res a la pila ja que no cal. # voltejarH: srl $t0, $a1, 1 # $t0 <- Width / 2 li $t1, 0 # i <- 0 fori: bge $t1, $a2, exiti # Mentre i < Height mul $t2, $t1, $a1 # SrcOffs <- i * Width add $t3, $t2, $a1 # DstOffs <- SrcOffs + Width addi $t3, $t3, -1 # DstOffs <- DstOffs - 1 li $t4, 0 # j <- 0 forj: bge $t4, $t0, exitj # Mentre j < Width / 2 add $t5, $t2, $t4 # SrcOffs + j sll $t5, $t5, 2 # ( SrcOffs + j ) * 4 add $t5, $t5, $a0 # Image + ( SrcOffs + j ) * 4 sub $t6, $t3, $t4 # DstOffs - j sll $t6, $t6, 2 # ( DstOffs - j ) * 4 add $t6, $t6, $a0 # Image + ( DstOffs - j ) * 4 lw $t7, 0($t5) # Intercanviar els píxels lw $t8, 0($t6) # calculats de la fila: sw $t7, 0($t6) # SrcOffset + j per sw $t8, 0($t5) # DstOffset - j addi $t4, $t4, 1 # j++ j forj # Propera iteració exitj: addi $t1, $t1, 1 # i++ j fori # Propera iteració exiti: jr $ra # Retonar a l'invocador .end .text # # void main ( void ) # # Exemple de crida a voltejarH ( Image, Width, Height ); # main: subu $sp, $sp, 4 # Fer espai a la pila sw $ra, 0($sp) # Guardar l'adreça de retorn # Els tres paràmetres per registre: la $a0, Image # Adreça de la Imatge lw $a1, Width($0) # Amplada lw $a2, Height($0) # Altura # Com que les rutines no modifiquen # els paràmetres, només cal que # s'escriguin un cop als registres jal inicialitzar # Inicialitzar la Imatge jal escriure # Escriure la Imatge jal voltejarH # Cridar a "voltejarH" jal escriure # Tornar a escriure la Imatge lw $ra, 0($sp) # Recuperar adreça de retorn addu $sp, $sp, 4 # Desempilar jr $ra # Retonar a l'invocador .end