Mini Curso de Ensamblador MIPS MARS> Guia paso a paso

cyberruelas 1 views 32 slides Sep 20, 2025
Slide 1
Slide 1 of 32
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32

About This Presentation

MIPS ensamblador course>
Arquitectura
Ejemplo b[asico y sencillo, explicado paso a paso


Slide Content

Mini Curso de Ensamblador (MIPS + MARS) Guía paso a paso con ejemplos y actividades Simulador MARS/SPIM (arquitectura MIPS32)

Simulador fiel a los reales: MARS/SPIM ¿Por qué MIPS? Arquitectura RISC sencilla, usada en cursos universitarios y libros. Convenciones claras de registros y llamadas a sistema. Simuladores MARS/SPIM permiten depurar paso a paso. Qué veremos Registros, memoria, E/S, control de flujo, funciones y pila. Buenas prácticas para generar código desde un compilador.

Cómo ejecutar en MARS (paso a paso) 1) Abre MARS (archivo .jar). 2) Archivo → New, pega tu código MIPS. 3) Ensambla: Run → Assemble (o F3). 4) Ejecuta: Run → Go (o F5). 5) Paso a paso: Run → Step (F7), observa registros y memoria. 6) Ventanas útiles: Registers, Data Segment, Text Segment, Console.

Clase 1 — Introducción y Hola Mundo Objetivos Comprender secciones .data y .text. Usar llamadas a sistema (syscall) para E/S básica. Paso a paso Crea etiquetas y reserva memoria con .asciiz. Carga dirección con la y llama a imprimir string. Finaliza el programa con syscall de salir.

Código — Clase 1: Hola Mundo # Hola Mundo en MIPS (MARS/SPIM) .data msg: .asciiz "Hola Mundo\n" .text main: li $v0, 4 # 4 = print_string la $a0, msg # $a0 = &msg syscall li $v0, 10 # 10 = exit syscall

Actividad guiada — Clase 1 A) Cambia el mensaje a tu nombre. B) Imprime dos líneas usando dos etiquetas distintas. C) Agrega un print_char (syscall 11) para imprimir '!'. Tip: usa la Console para verificar la salida.

Clase 2 — Registros y Operaciones Aritméticas Objetivos Cargar constantes con li; mover datos entre registros. Suma, resta, multiplicación y división. Nota: MARS permite pseudo-instrucciones mul/div con 3 operandos. Equivalentes reales usan mult/div + mflo/mfhi.

Código — Clase 2: Registros y Aritmética # Aritmética básica .text main: li $t0, 15 li $t1, 5 add $t2, $t0, $t1 # $t2 = 15 + 5 sub $t3, $t0, $t1 # $t3 = 15 - 5 # Opción 1 (pseudo-instrucciones MARS): mul $t4, $t0, $t1 # $t4 = 15 * 5 div $t5, $t4, $t1 # $t5 = (15*5)/5 = 15 # Opción 2 (instrucciones reales): # mult $t0, $t1 # LO = 15*5 # mflo $t4 # $t4 = LO # div $t4, $t1 # LO = (15*5)/5 # mflo $t5 # $t5 = LO li $v0, 10 syscall

Actividad guiada — Clase 2 Calcula ((15 + 5) * 2) / 5 y guarda cada resultado parcial en $t2, $t3, $t4. Imprime el resultado final con print_int (syscall 1).

Apoyo — Imprimir enteros y nueva línea # Imprimir enteros (syscall 1) y salto de línea .data nl: .asciiz "\n" .text main: li $t0, 42 li $v0, 1 # 1 = print_int move $a0, $t0 syscall li $v0, 4 # 4 = print_string la $a0, nl syscall li $v0, 10 syscall

Clase 3 — Memoria: .data, lw/sw Objetivos .word y .asciiz para definir datos estáticos. Cargar desde memoria con lw, guardar con sw. Usar etiquetas y la para direcciones.

Código — Clase 3: Acceso a memoria # Suma en memoria .data x: .word 7 y: .word 3 z: .word 0 .text main: lw $t0, x # $t0 = 7 lw $t1, y # $t1 = 3 add $t2, $t0, $t1 # $t2 = 10 sw $t2, z # z = 10 li $v0, 10 syscall

Actividad guiada — Clase 3 Declara a y b; guarda en c el doble de su suma: c = 2*(a+b). Imprime c en consola.

Clase 4 — Control de Flujo: if/else y bucles Objetivos Condicionales con beq/bne y comparaciones con slt. Bucles con etiquetas y saltos. MARS permite pseudo-instrucciones blt/bgt/bge/ble.

Código — Clase 4: If-Else # If-Else: imprimir si x > y .data msg_mayor: .asciiz "Mayor\n" msg_menor: .asciiz "Menor o igual\n" x: .word 9 y: .word 5 .text main: lw $t0, x lw $t1, y # Opción 1 (portátil): usar slt y beq/bne slt $t2, $t1, $t0 # $t2 = 1 si y < x (i.e., x > y) beq $t2, $zero, menor_igual mayor: li $v0, 4 la $a0, msg_mayor syscall j fin menor_igual: li $v0, 4 la $a0, msg_menor syscall fin: li $v0, 10 syscall

Código — Clase 4: Bucle while # Bucle while: suma 1..N .data N: .word 5 txt: .asciiz "Suma 1..N = " nl: .asciiz "\n" .text main: lw $t0, N # N li $t1, 1 # i = 1 li $t2, 0 # acc = 0 while: bgt $t1, $t0, done # pseudo-instrucción (MARS). Portátil: usar slt y beq. add $t2, $t2, $t1 # acc += i addi $t1, $t1, 1 # i++ j while done: li $v0, 4 la $a0, txt syscall li $v0, 1 move $a0, $t2 syscall li $v0, 4 la $a0, nl syscall li $v0, 10 syscall

Clase 5 — Funciones y Pila (Stack) Objetivos Convención de llamadas: $a0-$a3 (args), $v0-$v1 (ret). jal y jr $ra; preservación de $s0-$s7 por el callee. Uso de la pila: prologue/epilogue y $sp.

Código — Clase 5: Función simple # Función suma(a,b) -> $v0 .text main: li $a0, 7 li $a1, 8 jal suma move $t0, $v0 # resultado en $t0 li $v0, 10 syscall suma: add $v0, $a0, $a1 # retorno en $v0 jr $ra

Código — Clase 5: Stack y prologue/epilogue # Función cuadrado(n) con stack frame .text main: li $a0, 9 jal cuadrado move $t0, $v0 li $v0, 10 syscall # Convención: salvamos $ra y registros $s que usemos cuadrado: addi $sp, $sp, -8 # espacio para $ra y $s0 sw $ra, 4($sp) sw $s0, 0($sp) move $s0, $a0 # s0 = n (callee-saved) mul $v0, $s0, $s0 # v0 = n*n (pseudo). Real: mult s0,s0; mflo v0 lw $s0, 0($sp) lw $ra, 4($sp) addi $sp, $sp, 8 jr $ra

Tabla rápida de syscalls (MARS) 1 → print_int (usa $a0) 4 → print_string (usa $a0) 5 → read_int (retorna en $v0) 8 → read_string (usa $a0=buffer, $a1=tamaño) 10 → exit 11 → print_char (usa $a0)

Apoyo — Leer enteros con syscalls # Leer dos enteros y mostrarlos .data prompt1: .asciiz "Ingresa A: " prompt2: .asciiz "Ingresa B: " space: .asciiz " " nl: .asciiz "\n" .text main: # A li $v0, 4 la $a0, prompt1 syscall li $v0, 5 # read_int syscall move $t0, $v0 # B li $v0, 4 la $a0, prompt2 syscall li $v0, 5 syscall move $t1, $v0 # Mostrar A y B li $v0, 1 move $a0, $t0 syscall li $v0, 4 la $a0, space syscall li $v0, 1 move $a0, $t1 syscall li $v0, 4 la $a0, nl syscall li $v0, 10 syscall

Clase 6 — Proyecto Final (integrador) Objetivo: pedir dos números, imprimir suma y producto. Pasos 1) Lee A y B (syscall 5). 2) Calcula suma y producto (maneja overflow si usas mult real). 3) Imprime resultados con etiquetas claras. 4) Encapsula operaciones en funciones opcionales.

Código — Proyecto Final (esqueleto) # Proyecto Final — Esqueleto .data pA: .asciiz "Ingresa A: " pB: .asciiz "Ingresa B: " txtS: .asciiz "Suma = " txtP: .asciiz "Producto = " nl: .asciiz "\n" .text main: # Leer A li $v0, 4 la $a0, pA syscall li $v0, 5 syscall move $t0, $v0 # Leer B li $v0, 4 la $a0, pB syscall li $v0, 5 syscall move $t1, $v0 # Suma y producto add $t2, $t0, $t1 mul $t3, $t0, $t1 # real: mult $t0,$t1; mflo $t3 # Mostrar suma li $v0, 4 la $a0, txtS syscall li $v0, 1 move $a0, $t2 syscall li $v0, 4 la $a0, nl syscall # Mostrar producto li $v0, 4 la $a0, txtP syscall li $v0, 1 move $a0, $t3 syscall li $v0, 4 la $a0, nl syscall li $v0, 10 syscall

Buenas prácticas (pensando en compiladores) Respeta la convención de llamadas: caller/callee-saved. Minimiza accesos a memoria: usa registros. Evita pseudo-instrucciones si apuntas a portabilidad. Documenta el uso de registros temporales ($t) y salvados ($s). Separa datos (.data) y código (.text) con etiquetas claras.

Autoevaluación — Clase 1 1. ¿Qué diferencia hay entre .data y .text? 2. ¿Qué hace la instrucción 'la $a0, msg'? 3. ¿Qué valor se carga en $v0 para terminar un programa?

Autoevaluación — Clase 2 1. ¿Qué registros usarías para operaciones temporales? 2. ¿Cómo se imprime un número en consola? 3. ¿Qué instrucción mueve un valor entre registros?

Autoevaluación — Clase 3 1. ¿Qué diferencia hay entre .word y .asciiz? 2. Explica lw vs sw. 3. ¿Qué significa la instrucción 'la'?

Autoevaluación — Clase 4 1. ¿Qué hace slt? 2. ¿Cómo implementarías un bucle con etiquetas? 3. ¿Cuál es la diferencia entre beq y bne?

Autoevaluación — Clase 5 1. ¿Qué registros se usan para pasar argumentos? 2. ¿Qué significa 'jal' y 'jr $ra'? 3. ¿Qué se debe guardar en la pila al entrar a una función?

Autoevaluación — Clase 6 1. ¿Qué syscall permite leer un entero? 2. ¿Cómo mostrarías la suma y el producto en la consola? 3. ¿Qué pasa si no respetas la convención de registros?

Soluciones de Autoevaluación (resumen) Clase 1: .data=datos, .text=código; 'la' carga dirección; $v0=10 para salir. Clase 2: $t0-$t9; print_int (syscall 1); move destino, origen. Clase 3: .word=enteros, .asciiz=strings; lw=carga, sw=almacena; 'la'=load address. Clase 4: slt=establece <; bucles=etiquetas+jumps; beq=branch if equal, bne=branch if not equal. Clase 5: $a0-$a3 args, $v0-$v1 retorno; jal=jump and link, jr $ra=return; pila guarda $ra y $s. Clase 6: syscall 5=leer int; print_int/print_string para salida; romper convención=errores.

Rúbrica — Proyecto Final Entrada de datos (20%) Lee correctamente dos enteros desde consola. Operaciones (25%) Calcula suma y producto de forma correcta. Salida (20%) Imprime resultados con mensajes claros. Estructura y estilo (20%) Código comentado, uso correcto de registros y convención MIPS. Creatividad (15%) Agrega funciones propias, validaciones o mejoras adicionales.