Introducción 

a MIPS




Ciencias de la Computación III
Diego José Figueroa

Assembler


  • Lenguaje de bajo nivel

  • Capa de abstracción

  • Dependiente de la arquitectura

  • ¿Cuándo debemos usar assembler?

  • ¿Ventajas?

  • ¿Desventajas?

ISA


  • Vocabulario de assembler.

  • Conjunto de instrucciones de una arquitectura.

  • Abstracción entre hardware/software.

  • Provee un medio de unión entre hardware y software.

CISC vs RISC


  • Podemos clasificar una arquitectura de acuerdo a su ISA.

  • CISC
    • Complex Instruction Set Computer

  • RISC
    • Reduced Instruction Set Computer

CISC


  • Complex Instruction Set Computer

  • Muchas instrucciones

  • Instrucciones 'raras'.

  • Muchos modos de direccionamiento.

  • Pocos registros.

  • Instrucciones de tamaño variable.

  • Ej: Intel   :(

RISC


  • Reduced Instruction Set Computer.

  • Pocas instrucciones.

  • Muchos registros.

  • Pocos modos de direccionamiento
    • Sólo se opera entre registros.

  • Instrucciones de tamaño fijo.

  • Diseño más elegante.
    • Ej: MIPS :)

Cantidad de Operandos

Podemos clasificar una arquitectura en función de la cantidad de operandos explícitos en sus instrucciones:


    • Stack Machine (0-Address Machine)
      • add

    • Accumulator Machine (1-Address Machine)
      • add $1

    • Register File (2-Address Machine)
      • add $1 $2

    • 3 Address Machine
      • add $1 $2 $3

¿Por qué MIPS?


  • Diseño sumamente simple.

  • Creado con fines didácticos.

  • Convenio de llamadas a funciones simple.

  • Muchos registros (32).

  • Elegante y fácil de entender.

¿Por qué no x86?


  • Complejo (CISC).

  • Muchas instrucciones, convenios confusos.

  • Pocos registros (8).

MIPS Assembly Language


  • Comúnmente llamado MAL
  • Superset de las instrucciones soportadas en hardware.
  • El ensamblador convierte MAL a assembler real.
  • Brinda facilidades al programador.
  • Permite escribir código más conciso.

¿Cómo escribo un programa?


  • En MIPS cada instrucción ocupa una línea.
  • Lleva el formato
    • <operación> <destino> <operando1> <operando2>


    add $v0 $a0 $a1

¿Comentarios?


  • Cualquier cosa después de # es un comentario.


              # esto es un comentarioadd $0 $0 $0       # esto es otro comentario

Registros


  • MIPS está diseñado para operar mayormente entre registros.
  • Un registro 
    • es una memoria muy pequeña.
    • del tamaño de la arquitectura.
    • muy rápida.
  • MIPS provee 32 registros de 32 bits.
  • Cada registro puede almacenar cualquier cosa que quepa en 4 bytes.

Registros


  • Un registro NO es una variable.
  • Repitamos, un registro NO es una variable.
  • Un registro NO tiene un tipo de dato.




¿Por qué usamos registros?

Registros de MIPS


  • 32 registros:
    • de $0 a $31

  • Todos se pueden usar en cualquier operación.

  • Sin embargo, hay ciertos convenios, que asignan usos específicos a algunos registros.

  • Por facilidad a los registros se les dieron nombres, de acuerdo a su función.

$zero


  • $0 o $zero

  • Siempre vale 0.

  • Está alambrado a tierra, cualquier intento de escritura es ignorado.

  • Usado comúnmente para inicializaciones, o donde no importa el registro.

$s0 - $s7


  • $16 a $23.

  • Conocidos como saved registers, sobreviven las llamadas a funciones.

  • Es decir, no se modifican al llamar a una función.

  • Esto permite que se usen para guardar valores importantes y cosas que queramos mantener al llamar a una función.

$t0 - $t9


  • $8 a $15 más $24 y $25.

  • Registros temporales, no se preservan al llamar a una función.

  • Utilizados para valores temporales o poco importantes.


a = b+(c+d)    # c + d es temporal

$a0 - $a3


  • $4 a $a7.

  • Para paso de argumentos.

  • Permiten enviar los primeros 4 argumentos a una función.

$v0 y $v1


  • $2 y $3.

  • Utilizados para devolver resultados de una función.

  • Todas las funciones deben colocar sus resultados en estos registros.

$sp


  • $29

  • Conocido como Stack Pointer.

  • Apunta al stack, se utiliza para administrar el stack.

  • Utilizando $sp se puede pedir/reservar espacio en el stack.

  • Más de esto, más adelante.

$ra


  • $31

  • Conocido como Return Address.

  • Se utiliza para guardar la dirección de retorno de una función.

  • Las funciones, cuando terminan deben regresar a la instrucción que sigue a la instrucción que le llamó, $ra almacena esa dirección.

$gp, $fp


  • $28 y $30.

  • Punteros, Global Pointer y Frame Pointer.

  • No necesitan usarlos, por el momento.

$at


  • $1

  • Conocido como Assembler temporary.

  • Registro temporal, utilizado por el ensamblador.



El programador NO debe utilizar 

este registro.

$k0, $k1


  • Utilizados por el kernel del sistema operativo.

  • Sirven para manejo de excepciones/interrupciones.





El programador NO debe usar estos

 registros.






 add $s0 $s1 $s2

Instrucciones Aritméticas y Lógicas


  • Las instrucciones aritméticas tienen formato de 3 operandos. El primer operando es el destino. Los dos siguientes son operandos.


add $s0 $s1 $s2      # $s0 <- $s1 + $s2





  • Los operandos pueden ser ÚNICAMENTE registros. No direcciones de memoria, ni valores constantes.




a = b + c + d - e;  // a -> $s0, b -> $s1                    // c -> $s2, d -> $s3                    // e -> $s4
add $t0 $s1 $s2 # $t0 <- $s1 + $s2add $t0 $t0 $s3 # $t0 <- $t0 + $s3sub $s0 $t0 $s4 # $s0 <- $t0 - $s4

Instrucciones Aritméticas y Lógicas


  • add
  • sub
  • and (&)
  • or (|)
  • xor (^)
  • sll (<<)
  • srl, sra (>>)



  • ¿Y si queremos operar con constantes?

    Aritméticas y Lógicas Inmediatas


    • El tercer argumento es una constante, en vez de un registro.

    • Sólo se permiten constantes de hasta 16bits.


     addi $s0 $s1 10

    • Se distinguen por la terminación en i.

    • Aplica para todas las instrucciones anteriores.

    Corrimientos

    • sll          # shift left logical
    • srl         # shift right logical
    • sra        # shift right arithmetical

    • Formato
      • operación rd rt shamt
        • operación es uno de:  sll, srl, o sra.
        • rd es el registro destino.
        • rt es el registro a correr sus bits.
        • shamt es la cantidad de bits a correr.

              sll $s0 $s1 16

    Corrimientos


    • Existe una versión variable, recibe la cantidad de bits a correr en un registro en vez de una constante.

    • sllv
    • srlv
    • srav



             sllv $s0 $s1 $t0

    Multiplicación


    • Potencialmente puede producir un número de 64bits.
    • Por lo que puede tomarse un tiempo en calcular.

    • mult, recibe 2 argumentos:
      • rs -> primer registro a multiplicar
      • rt -> segundo registro a multiplicar

    • El resultado se coloca en 2 registros especiales:
      • La parte alta (32 bits más a la izq.) en el registro hi.
      • La parte baja (32 bits más a la der.) en el registro lo.

    mult $t0 $t1

    Multiplicación


    • Para obtener el resultado es necesario sacarlo de hi y/o lo.
    • Para eso se utiliza:
      • mfhi
      • mflo
    • Reciben un argumento, el registro a donde se copiará el valor.



    mult $t0 $t1mflo $s0         # $s0 = $t0 * $t1

    División


    • Funciona de modo similar a la multiplicación.

    • Coloca el cociente en lo.

    • Coloca el residuo en hi.



     div $t0 $t1 mflo $s0        # $s0 = $t0 / $t1

    Valores inmediatos


    • li
      • Carga un valor inmediato (constante) a un registro.


     li $t0 10           # $t0 = 10 li $t1 'a'          # $t1 = 'a'

    Lectura de Memoria


    • lb      -  Load byte
    • lh      -  Load half-word
    • lw     -  Load word
    • ld      -  Load double

      lw $s0 0($sp)   # $s0 = *(0+$sp)  lw $s1 4($sp)   # $s1 = *(4+$sp)

    • El offset es un inmediato de 16 bits con signo, que se suma a la dirección contenida en el registro.

    • El registro de la dirección, no se modifica.

    Escritura de Memoria


    • sb       -   Store byte
    • sh       -   Store half-word
    • sw       -   Store word
    • sd       -   Store double


    • Funciona de la misma forma que los anteriores, pero escriben a memoria en vez de leerla.


     sw $t0 0($sp)    # *(0+$sp) = $t0

    Accesos a Memoria



    • lw/sw  mueven un word desde/hacia la memoria.
      • Deben hacerse accesos a direcciones word-aligned.

    • lh/sh   mueven un half-word (2 bytes) desde/hacia la memoria.
      • Deben hacerse accesos a direcciones múltiplo de 2.

    • lb/sb   mueven un byte (un char) desde/hacia la memoria.

    Compilemos C



    a = b + c;f = (g + h) – (i + j);

    // a -> $s0, b -> $s1, c -> $s2
    // f -> $s3, g -> $s4, h -> $s5// i -> $s6, j -> $s7
    ¿Equivalente en MIPS?

    Compilemos C


    string[i+1] = string[i] + 32;

    // string -> $s0// i -> $s1

    ¿Equivalente en MIPS?

    Directivas


    • Etiqueta
      • Simboliza la dirección absoluta de la instrucción inmediatamente siguiente.

     main:   # main es una etiqueta         add $v0 $s0 $0         jr $ra

    • .text
      • Directiva que indica al ensamblador que lo siguiente es el texto del programa.
    • .data
      • Directiva que indica al ensamblador que lo que sigue es data global.

    Más directivas...


    • .byte  <value>
      • Reserva 1 byte en memoria.

    • .word <value>
      • Reserva 1 word en memoria.

    • .space <n>
      • Reserva <n> bytes consecutivos de memoria.
      • Recuerden word-aligned!

    • .asciiz <string>
      • Reserva espacio para el <string> indicado, agrega el '\0' al final.


    .data msg: .asciiz "hello world!\n"
    .text main: la $a0 msg # carga el mensaje   li $v0 4 # print_string(msg) syscall   li $v0 10 # exit syscall

    Title

    05 - Intro MIPS

    By Diego Figueroa

    05 - Intro MIPS

    • 1,032