I S A

2,348 views

Published on

Published in: Technology
1 Comment
0 Likes
Statistics
Notes
  • gracias muy buen aporte
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Be the first to like this

No Downloads
Views
Total views
2,348
On SlideShare
0
From Embeds
0
Number of Embeds
46
Actions
Shares
0
Downloads
78
Comments
1
Likes
0
Embeds 0
No embeds

No notes for slide

I S A

  1. 1. ISA Instruction Set Architecture Cecilia Hernández [email_address]
  2. 2. Estructura de un Sistema Computacional
  3. 3. Traduciendo y ejecutando un programa Programa C Programa en lenguaje ensamblador Cód. Objeto: módulo en lenguaje de máquina Cod. Objeto: Bibliotecas Cod. Ejecutable: Prog. Leng. Máquina Memoria Compilador Ensamblador Linker Loader
  4. 4. Interfaz HW/SW
  5. 5. Convenciones <ul><li>UNIX </li></ul><ul><ul><li>P.c : archivo fuente en lenguaje C </li></ul></ul><ul><ul><li>P.s : archivo fuente en lenguaje ensamblador </li></ul></ul><ul><ul><li>P.o : archivo objeto </li></ul></ul><ul><ul><li>P.a : biblioteca estáticamente linkeada </li></ul></ul><ul><ul><li>P.so : biblioteca dinámicamente linkeada </li></ul></ul><ul><ul><li>a.out : archivo ejecutable por defecto </li></ul></ul><ul><li>MS-DOS </li></ul><ul><ul><li>P.C : archivo fuente en lenguaje C </li></ul></ul><ul><ul><li>P.ASM : archivo fuente en lenguaje ensamblador </li></ul></ul><ul><ul><li>P.OBJ : archivo objeto </li></ul></ul><ul><ul><li>P.LIB : biblioteca estaticamente linkeada </li></ul></ul><ul><ul><li>P.DLL : biblioteca dinámicamente linkeada </li></ul></ul><ul><ul><li>P.EXE: archivo ejecutable </li></ul></ul>
  6. 6. Qué es una instrucción? <ul><li>Comando que le dice a la CPU que operación realizar </li></ul><ul><ul><li>Mediante código de operación </li></ul></ul><ul><ul><ul><li>Todas las instrucciones están codificadas </li></ul></ul></ul><ul><ul><li>Donde se encuentran los operandos necesarios para ejecutar la operación </li></ul></ul><ul><li>ISA de una instrucción especifica </li></ul><ul><ul><li>Código de operación </li></ul></ul><ul><ul><li>Cuántos operandos son necesarios, tipos, tamaños, ubicación </li></ul></ul><ul><li>Operandos </li></ul><ul><ul><li>Registros (enteros, punto flotante, PC) </li></ul></ul><ul><ul><li>Dirección de memoria </li></ul></ul><ul><ul><li>Constantes </li></ul></ul>
  7. 7. Ejecución de instrucción de máquina <ul><li>CPU ejecuta instrucciones de un programa ciclo </li></ul><ul><li>Instrucciones especifican operaciones sobre operandos y generan resultados </li></ul><ul><li>Datos pueden encontrarse en memoria (RAM, ROM) o en registros internos al procesador </li></ul><ul><li>Instrucciones pueden también modificar el flujo de control (saltos, llamadas a procedimiento) </li></ul><ul><li>Instrucciones pueden crear excepciones </li></ul>
  8. 8. Arquitectura de Conjunto de Instrucciones ISA <ul><li>Visión del programador de bajo nivel o del compilador </li></ul><ul><li>Elementos que definen la ISA </li></ul><ul><ul><li>Operaciones (instrucciones) </li></ul></ul><ul><ul><ul><li>suma, multiplicación, saltos, entrada/salida </li></ul></ul></ul><ul><ul><li>Tipos de datos </li></ul></ul><ul><ul><ul><li>Entero, punto flotante, strings </li></ul></ul></ul><ul><ul><li>Número y forma de acceder a operandos y resultados </li></ul></ul><ul><ul><ul><li>0,1,2,3 operandos, residentes en memoria o registros internos </li></ul></ul></ul><ul><ul><li>Formato (codificación) de instrucciones y datos </li></ul></ul><ul><ul><ul><li>Complemento a 2, punto flotante IEEE </li></ul></ul></ul><ul><ul><li>Espacio de memoria y número de registros </li></ul></ul><ul><ul><li>Condiciones excepcionales </li></ul></ul><ul><ul><ul><li>División por cero, excepción de memoria virtual, llamada a sistema operativo </li></ul></ul></ul>
  9. 9. MIPS <ul><li>Una familia de procesadores </li></ul><ul><ul><li>32 bits : R2000/3000 </li></ul></ul><ul><ul><li>64 bits : R4000/4400, R10000 </li></ul></ul><ul><li>Partió como proyecto de investigación en Stanford y luego formó compañía MIPS, que posteriormente compró Silicon Graphics </li></ul><ul><li>Proviene de máquinas DEC </li></ul><ul><li>MIPS es RISC </li></ul><ul><li>Actualmente usados en mercados de sistemas encrustrados o embebidos </li></ul><ul><ul><li>Routers CISCO, modems cable (modula señales de comunicación sobre infraestructura de TV cable), impresoras laser, Sony playstation 2, computadores handheld </li></ul></ul><ul><ul><li>http://www.mips.com/content/Markets/MIPSBased/content_html </li></ul></ul>
  10. 10. Aplicaciones del procesador MIPS
  11. 11. Almacenamiento en MIPS
  12. 12. Registros MIPS <ul><li>Registros de propósito general </li></ul><ul><ul><li>Un banco de registro de 32 registros de 32 bits direccionados $0, $1,…, $31 </li></ul></ul><ul><ul><ul><li>Aritmética entera y lógica cálculo de direcciones, operaciones de propósito específico como Puntero al Stack (pila) </li></ul></ul></ul><ul><ul><li>Un banco de registros punto flotante. Registros de 32 bits direccionados $f1, $f2,…$f31 usados para aritmética punto flotante </li></ul></ul><ul><li>Registros de propósito específico </li></ul><ul><ul><li>2 registros de 32 bits (HI, LO) usados para multiplicación y división </li></ul></ul><ul><ul><li>Un registro Contador de Programas (PC) </li></ul></ul><ul><ul><li>Registro de estado (coprocesador 0) almacena causa de excepción datos relacionados a excepción </li></ul></ul><ul><li>ISA con registros generales también son llamadas Ortogonales </li></ul><ul><ul><li>Operaciones son independientes de los registros </li></ul></ul><ul><li>ISA MIPS define Convención Software para uso de registros </li></ul><ul><ul><li>No es obligatoria, no es forzada por hardware </li></ul></ul>
  13. 13. Convención de uso de registros MIPS $0 zero constante cero $1 at reservado para ensamblador $2 v0 evaluación de expresiones y $3 v1 resultados de funciones $4 a0 argumentos a funciones $5 a1 $6 a2 $7 a3 $8 t0 variables temporales respaldadas por función . que invoca . (función invocada puede . sobreescribir) $15 t7 $16 s0 temporales respaldados por . función invocada . (función que invoca no respalda) . $23 s7 $24 t8 temporales (adicionales) $25 t9 $26 k0 reservados para sistema operativo $27 k1 $28 gp puntero a variables globales $29 sp puntero a tope del stack $30 fp puntero a base del stack $31 ra dirección de retorno de función
  14. 14. MIPS=RISC = Arquitectura load/store <ul><li>ALU opera sólo en operandos que están en registros </li></ul><ul><ul><li>A excepción de enteros pequeños que pueden estar en la misma instrucción, como se verá más adelante (caso de instrucciones con componente immediato) </li></ul></ul><ul><ul><li>Implica que variables deben estar “loaded” en registros (si vienen de la memoria) antes de ejecutar otro tipo de instrucciones </li></ul></ul><ul><li>Las únicas instrucciones que accesan la memoria son del tipo load/store </li></ul><ul><ul><li>Se necesitan instrucciones explícitas para realizar operaciones de “load” y “store” </li></ul></ul><ul><ul><li>Resultados obtenidos de otras operaciones deben ser “stored” en memoria </li></ul></ul>
  15. 15. Ejemplo <ul><li>Sentencia expresada en un lenguaje de programación de alto nivel </li></ul><ul><ul><li>x = y + z </li></ul></ul><ul><ul><li>w = x + y </li></ul></ul><ul><li>Se traduce en lenguaje assembly (ensamblador) como (asumiendo operandos están en memoria) </li></ul><ul><ul><li>load y en registro ry </li></ul></ul><ul><ul><li>load z en registro rz </li></ul></ul><ul><ul><li>rx <- ry + rz </li></ul></ul><ul><ul><li>store rx en x, no borra el resultado en rx </li></ul></ul><ul><ul><li>rt <- rx + ry </li></ul></ul><ul><ul><li>store rt en w </li></ul></ul>
  16. 16. Programando en lenguaje ensamblador <ul><li>Usar muchos comentarios para describir lo que se esta haciendo </li></ul><ul><li>Usar words en lugar de bytes en lo posible </li></ul><ul><li>La siguiente dirección a dato expresado en words es dirección + 4 </li></ul><ul><li>Direcciones de words son divisibles por 4 </li></ul>
  17. 17. Tipos de instrucciones en MIPS <ul><li>Aritméticas </li></ul><ul><ul><li>Operaciones con enteros (con y sin signo) </li></ul></ul><ul><ul><li>Operaciones con punto flotante </li></ul></ul><ul><li>Lógicas y de desplazamiento </li></ul><ul><ul><li>Ands, ors, entre otros </li></ul></ul><ul><ul><li>Desplazamiento de bits (izquierda, derecha) </li></ul></ul><ul><li>Load/store </li></ul><ul><ul><li>Variables son cargadas en registros (load) </li></ul></ul><ul><ul><ul><li>Desde memoria a registros o constantes a registros </li></ul></ul></ul><ul><ul><li>Resultados se graban en memoria (store) </li></ul></ul><ul><li>Comparación de valores en registros </li></ul><ul><li>Saltos condicionales (branches) y absolutos (jumps) </li></ul><ul><ul><li>Manipulan control de flujo </li></ul></ul><ul><ul><li>Incluyen llamados a procedimientos y retornos </li></ul></ul>
  18. 18. Aritmética entera <ul><li>Números pueden ser con o sin signo </li></ul><ul><li>Instrucciones aritméticas (+,-,/,*) existen para ambos tipos de enteros (diferenciado por código de operación) </li></ul><ul><ul><li>add, addu, sub, subu </li></ul></ul><ul><ul><li>addi, addiu, subi, subiu </li></ul></ul><ul><ul><li>mult, multu, div, divu </li></ul></ul><ul><li>Números con signo son representados en complemento a 2 </li></ul><ul><ul><li>En caso de overflow se genera excepción </li></ul></ul>
  19. 19. Notación en SPIM <ul><li>Código operación rd, rs, rt </li></ul><ul><ul><li>Instrucciones aritmeticas, lógicas, comparaciones </li></ul></ul><ul><li>Código operación rt, rs, immediato </li></ul><ul><ul><li>Instrucciones aritméticas, lógicas, load/store, saltos condicionales </li></ul></ul><ul><li>Código operación immediato </li></ul><ul><ul><li>Instrucciones de salto absoluto </li></ul></ul><ul><li>Donde: </li></ul><ul><ul><li>rd siempre es el registro destino </li></ul></ul><ul><ul><li>rs siempre es el registro fuente (de sólo lectura) </li></ul></ul><ul><ul><li>rt puede ser fuente o destino depende del código de operación </li></ul></ul><ul><ul><li>Immediato es una constante de 16 bits (con o sin signo) </li></ul></ul>
  20. 20. Instrucciones aritméticas en SPIM <ul><li>No confundirlo con la codificación de instrucciones que se verá pronto </li></ul># rd = rs - rt rd, rs, rt sub # rt = rs + immed rt, rs, immediato addi # rd = rs + rt rd, rs, rt add Comentarios Operandos Código Operación
  21. 21. Instrucciones aritméticas <ul><ul><li>add $1,$2,$3 #$1 = $2 + $3. Posible overflow </li></ul></ul><ul><ul><li>sub $1,$2,$3 #$1 = $2 – $3. Posible overflow </li></ul></ul><ul><ul><li>addi $1,$2,100 #$1 = $2 + 100. Posible overflow </li></ul></ul><ul><ul><li>addu $1,$2,$3 #$1 = $2 + $3. Suma sin signo sin overflow </li></ul></ul><ul><ul><li>subu $1,$2,$3 #$1 = $2 – $3. Resta sin signo sin overflow </li></ul></ul><ul><ul><li>addiu $1,$2,100 #$1 = $2 + 100. Suma sin signo sin overflow </li></ul></ul><ul><ul><li>mult $2,$3 #HI, LO = $2 x $3 </li></ul></ul><ul><ul><li>multu$2,$3 #HI, LO = $2 x $3. Producto sin signo </li></ul></ul><ul><ul><li>div $2,$3 #LO = $2 ÷ $3 (cuociente) #HI = $2 mod $3 (resto) </li></ul></ul><ul><ul><li>divu $2,$3 #LO = $2 ÷ $3 (cuociente sin signo) #HI = $2 mod $3 (resto) </li></ul></ul><ul><ul><li>abs $1, $2 #$1 = |$2|. Valor absoluto </li></ul></ul>
  22. 22. Ejemplos Add $8,$9,$10 #$8=$9+$10 Add $t0,$t1,$t2 #$t0=$t1+$t2 Sub $s2,$s1,$s0 #$s2=$s1-$s0 Addi $a0,$t0,20 #$a0=$t0+20 Addi $a0,$t0,-20 #$a0=$t0-20 Addi $t0,$0,0 #clear $t0 Sub $t5,$0,$t5 #$t5 = -$t5
  23. 23. Instrucciones lógicas <ul><ul><li>and $1,$2,$3 #$1 = $2 && $3 </li></ul></ul><ul><ul><li>or $1,$2,$3 #$1 = $2 || $3 </li></ul></ul><ul><ul><li>xor $1,$2,$3 #$1 = ~($2 || $3) </li></ul></ul><ul><ul><li>nor $1,$2,$3 #$1 = ~($2 || $3) </li></ul></ul><ul><ul><li>andi $1,$2,10 #$1 = $2 && 10 </li></ul></ul><ul><ul><li>ori $1,$2,10 #$1 = $2 || 10 </li></ul></ul><ul><ul><li>xori $1, $2,10 #$1 = ~$2 && ~10 </li></ul></ul><ul><ul><li>sll $1,$2,10 #$1 = $2 << 10. Desplazamiento lógico </li></ul></ul><ul><ul><li>srl $1,$2,10 #$1 = $2 >> 10. Desplazamiento lógico </li></ul></ul><ul><ul><li>sra $1,$2,10 #$1 = $2 >> 10. Desplazamiento aritmético </li></ul></ul><ul><ul><li>sllv $1,$2,$3 #$1 = $2 << $3. Desplazamiento lógico </li></ul></ul><ul><ul><li>srlv $1,$2, $3 #$1 = $2 >> $3. Desplazamiento lógico </li></ul></ul><ul><ul><li>srav $1,$2, $3 #$1 = $2 >> $3. Desplazamiento aritmético </li></ul></ul>
  24. 24. Movimiento entre registros <ul><ul><li>move $2,$3 # $2  $3 (PseudoInstrucción) </li></ul></ul><ul><ul><li>mflo $2 # $2  LO. Copia LO en $2 </li></ul></ul><ul><ul><li>mfhi $2 # $2  HI. Copia HI en $2 </li></ul></ul><ul><ul><li>mtlo $2 # LO  $2. Copia en LO $2 </li></ul></ul><ul><ul><li>mthi $2 # $2  HI. Copia en HI $2 </li></ul></ul><ul><ul><li>lui $3, 500 # $3  500 * 2 16 . Carga el valor # constante de 16b en la parte # más significativa de $3 </li></ul></ul><ul><ul><li>mfc0 $1, $epc # $1  dirección de instrucción que # causó excepción </li></ul></ul>
  25. 25. Acceso a memoria <ul><li>Mueven datos entre registros y memoria </li></ul><ul><li>Modo de direccionamiento único </li></ul><ul><ul><li>base + desplazamiento </li></ul></ul><ul><ul><li>Base: contenido de registro </li></ul></ul><ul><ul><li>Desplazamiento: constante de 16 bits </li></ul></ul><ul><ul><li>Load </li></ul></ul><ul><li>lw rt,rs,offset #rt = Memory[rs+offset] </li></ul><ul><li>lw $1, 100($2) # $1  Mem[$2 + 100] </li></ul><ul><ul><li>Store </li></ul></ul><ul><li>lw rt,rs,offset #Memory[rs+offset]=rt </li></ul><ul><li>sw $1, 100($2) # $1 -> Mem[$2 + 100] </li></ul>
  26. 26. Instrucciones load/store <ul><ul><li>sw $3, 500($2) # Mem(500+$2)  $3. Almacena 32b </li></ul></ul><ul><ul><li>sh $3, 500($2) # Mem(500+$2)  $3. Almacena 16b </li></ul></ul><ul><ul><li>sb $3, 500($2) # Mem(500+$2)  $3. Almacena 8b </li></ul></ul><ul><ul><li>lw $3, 500($2) # $3  Mem(500+$2). Carga 32b </li></ul></ul><ul><ul><li>lh $3, 500($2) # $3  Mem(500+$2). Carga 16b </li></ul></ul><ul><ul><li>lhu $3, 500($2) # $3  Mem(500+$2). # Carga 16b sin signo </li></ul></ul><ul><ul><li>lb $3, 500($2) # $3  Mem(500+$2). Carga 8b </li></ul></ul><ul><ul><li>la $3, Label # $3  Address. Carga la dirección # efectiva asociada a Label en $3 </li></ul></ul><ul><ul><li>Dirección efectiva : número que indica dirección del operando en memoria </li></ul></ul>
  27. 27. Algunas pseudoinstrucciones move $4, $5 # $4  $5 # or $4, $zero, $5 li $4, 100 # $4  100 # ori $4, $zero, 100 la $4, LABEL32 # $4  LABEL # lui $4, LABEL 16bsuperiores # ori $4, $4, LABEL 16binferiores bgt $4, CTE, LABEL # if ($4 > CTE) goto LABEL # slti $at, $4, CTE+1 # beq $at, $zero, LABEL
  28. 28. Ejemplo int a, b, acum; … acum = acum + a * b; # Dirección de memoria de ‘a’ en rótulo DIR_A # Dirección de memoria de ‘b’ en rótulo DIR_B # Dirección de memoria ‘acum’ en rótulo DIR_ACUM la $v0, DIR_A # cargar dirección de a la $v1, DIR_B # cargar dirección de b lw $t0, 0($v0) # leer a lw $t1, 0($v1) # leer b mul $t2, $t0, $t1 # t2 = a * b la $v2, DIR_ACUM # cargar dirección de acum lw $t3, 0($v2) # leer acum add $t3, $t3, $t2 # $t3 = acum + a * b sw $t3, 0($v2) # guardar acum 10 2 DIR_A DIR_B DIR_ACUM 50 Memoria $v0 $v1 $v2 $t0 $t1 $t2 $t3 1000 1012 10 2 20 1024 50 70 70 1000 1004 1008 1012 1016 1020 1024 a b acum
  29. 29. Ejemplo typedef struct { int x; int y; } coord; coord c1, c2; … int dist; dist = abs(c2.x – c1.x) + abs(c2.y – c1.y); # Dirección de memoria de ‘c1’ en rótulo DIR_C1 # Dirección de memoria de ‘c2’ en rótulo DIR_C2 # Dirección de memoria de ‘dist’ en rótulo DIR_DIST la $v0, DIR_C1 # cargar dirección de c1 la $v1, DIR_C2 # cargar dirección de c2 lw $t0, 0($v0) # leer c1.x lw $t1, 0($v1) # leer c2.x sub $t2, $t1, $t0 # t2 = c2.x – c1.x abs $t3, $t2 # t3 = abs(c2.x – c1.x) lw $t0, 4($v0) # leer c1.y lw $t1, 4($v1) # leer c2.y sub $t2, $t1, $t0 # t2 = c2.y – c1.y abs $t4, $t2 # t4 = abs(c2.y – c1.y) add $t3, $t3, $t4 # t3 = abs(c2.x – c1.x) + # abs(c2.y – c1.y) la $v0, DIR_DIST # cargar dirección de dist sw $t3, 0($v0) # dist = abs(c2.x – c1.x) + # abs(c2.y – c1.y) c1.x c1.y c2.x c2.y Direcciones de memoria DIR_C1 DIR_C1 + 4 DIR_C2 DIR_C2 + 4 DIR_DIST dist Memoria
  30. 30. Ejecución condicional de instrucciones <ul><li>Permiten ejecutar partes de un programa sólo si se cumple una determinada condición </li></ul><ul><ul><li>Ej. Estructuras tipo if-else, for, while, switch-case </li></ul></ul><ul><ul><li>Típicamente saltos, pero también escritura a registro </li></ul></ul><ul><li>¿Cómo especificar la condición? </li></ul><ul><ul><li>Comparación en la instrucción </li></ul></ul><ul><ul><ul><li>bgt r1, r2, ADDR # if r1 > r2 goto ADDR </li></ul></ul></ul><ul><ul><li>Registro de condición (MIPS) </li></ul></ul><ul><ul><ul><li>cmp r1, r2, r3 # r3 = signo (r1-r2) bgtz r1, ADDR # if r1 > 0 goto ADDR </li></ul></ul></ul>
  31. 31. Instrucciones ISA MIPS <ul><li>Instrucciones de comparación </li></ul><ul><ul><li>Evalúa condición entre dos operandos </li></ul></ul><ul><ul><ul><li>Resultado es VERDADERO o FALSO </li></ul></ul></ul><ul><ul><li>Utilizan registro de condición </li></ul></ul><ul><ul><ul><li>Resultado de comparación se almacena en registro destino </li></ul></ul></ul><ul><ul><ul><li>FALSO  regDest = 0 </li></ul></ul></ul><ul><ul><ul><li>VERDADERO  regDest = 1 </li></ul></ul></ul>Ejemplo: add $1, $2, $3 slt $4, $1, $0 # if $1 < $0 then $4 = 1 # else #4 = 0
  32. 32. Algunas instrucciones de comparación <ul><ul><li>slt $1,$2,$3 # if ($2 < $3) $1= 1 else $1 = 0 </li></ul></ul><ul><ul><li>sltu $1,$2,$3 # if ($2 < $3) $1 = 1 else $1 = 0 (sin signo) </li></ul></ul><ul><ul><li>slti $1, $2, 100 # if ($2 < 100) $1 = 1 else $1 = 0 </li></ul></ul><ul><ul><li>sltiu $1, $2, 100 # if ($2 < 100) $1 = 1 else $1 = 0 (sin signo) </li></ul></ul><ul><ul><li>Pseudoinstrucciones (se traducen en más de una instrucción de máquina): </li></ul></ul><ul><ul><li>seq $1, $2, $3 $if ($2 == $3) $1 = 1 else $1 = 0 </li></ul></ul><ul><ul><li>sne $1, $2, $3 $if ($2 != $3) $1 = 1 else $1 = 0 </li></ul></ul><ul><ul><li>sgt $1, $2, $3 $if ($2 > $3) $1 = 1 else $1 = 0 </li></ul></ul><ul><ul><li>sge $1, $2, $3 $if ($2 >= $3) $1 = 1 else $1 = 0 </li></ul></ul><ul><ul><li>sle $1, $2, $3 $if ($2 <= $3) $1 = 1 else $1 = 0 </li></ul></ul><ul><ul><li>Y otras… </li></ul></ul>
  33. 33. Instrucciones de salto MIPS <ul><li>Saltos condicionales </li></ul><ul><ul><li>beq $1,$2,CLabel # if ($1==$2) goto CLabel ; </li></ul></ul><ul><ul><li>bne $1,$2,CLabel # if ($1!=$2) goto CLabel ; </li></ul></ul><ul><ul><li>bgez $1, Clabel # if ($1 >=0) goto Clabel </li></ul></ul><ul><ul><li>bgtz, $1, Clabel # if ($1 >0) goto Clabel </li></ul></ul><ul><ul><li>blez, $1, Clabel # if ($1<=0) goto Clabel </li></ul></ul><ul><ul><li>bltz $1, Clabel # if ($1<0) goto CLabel </li></ul></ul><ul><ul><li>bge $1,$2,CLabel # if ($1>=$2) goto CLabel ; </li></ul></ul><ul><ul><li>bgt $1,$2,CLabel # if ($1>$2) goto CLabel ; </li></ul></ul><ul><ul><li>bgtu $1,$2,CLabel # if ($1>$2) goto CLabel ; </li></ul></ul><ul><ul><li># Comparación sin signo </li></ul></ul><ul><ul><li>ble $1,$2,CLabel # if ($1<=$2) goto CLabel ; </li></ul></ul><ul><ul><li>blt $1,$2,CLabel # if ($1<$2) goto CLabel ; </li></ul></ul><ul><ul><li>bltu $1,$2,CLabel # if ($1<$2) goto CLabel ; </li></ul></ul><ul><ul><li># Comparación sin signo </li></ul></ul>
  34. 34. Instrucciones de transferencia de control <ul><li>Registro de contador de programa </li></ul><ul><ul><li>Program Counter (PC) </li></ul></ul><ul><ul><li>Almacena dirección de siguiente instrucción a ejecutar </li></ul></ul><ul><ul><li>Por defecto, instrucción físicamente siguiente a la actual (PC  PC + 4) </li></ul></ul><ul><li>Modificación del flujo de control de un programa </li></ul><ul><ul><li>Tipos de salto (especificación de dirección destino) </li></ul></ul><ul><ul><ul><li>Absoluto: instrucción especifica directamente dirección destino </li></ul></ul></ul><ul><ul><ul><li>Relativo: instrucción especifica desplazamiento respecto de instrucción actual </li></ul></ul></ul><ul><ul><li>Tipos de salto (ejecución condicional) </li></ul></ul><ul><ul><ul><li>Incondicional: salto se realiza de todas formas </li></ul></ul></ul><ul><ul><ul><li>Condicional: salto se realiza sólo si se cumple una condición </li></ul></ul></ul><ul><ul><li>La mayoría de las ISA usan dos tipos de salto </li></ul></ul><ul><ul><ul><li>jump: absoluto e incondicional </li></ul></ul></ul><ul><ul><ul><li>branch: relativo y condicional </li></ul></ul></ul>
  35. 35. Saltos <ul><ul><li>Otros tipos de salto </li></ul></ul><ul><ul><ul><li>Salto a procedimiento : almacena dirección de retorno </li></ul></ul></ul><ul><ul><ul><li>Retorno de procedimiento : retorna a instrucción siguiente a la que hizo el salto a procedimiento </li></ul></ul></ul><ul><ul><ul><li>Llamado a sistema : salta a dirección predeterminada y pasa a modo supervisor </li></ul></ul></ul><ul><ul><ul><li>Retorno de excepción o llamado a sistema : retorna a instrucción que provocó excepción o llamado a sistema, y restaura modo usuario </li></ul></ul></ul>
  36. 36. Instrucciones de salto MIPS <ul><li>Saltos absolutos </li></ul><ul><ul><li>j CLabel # PC  CLabel </li></ul></ul><ul><li>Saltos a procedimiento </li></ul><ul><ul><li>jal CLabel # $ra  PC; PC  CLabel; </li></ul></ul><ul><ul><li>bgezal $1, CLabel # if ($1>=0) $ra = PC; PC = Clabel </li></ul></ul><ul><ul><li>Recordar que, durante la ejecución de una instrucción, PC contiene la dirección de la siguiente instrucción a ejecutar </li></ul></ul><ul><ul><li>$ra = $31 </li></ul></ul><ul><li>Saltos indexados </li></ul><ul><li>jr $ra # PC  $ra </li></ul><ul><li>jalr $1, $2 # $2  PC + 4; PC  $1 </li></ul>
  37. 37. Ejemplo Código assembly para el siguiente código C: int a = 10, b = 5; int c; … if (a > b) c = a – b; else c = b – a; c = c + 10; Compilador asigna: a  $t0 b  $t1 c  $t2 li $t0, 10 # a = 10 li $t1, 5 # b = 5 sle $t3, $t0, $t1 # a <= b ? bgtz $t3, ELSE # if a <= b goto ELSE sub $t2, $t0, $t1 # c = a - b j FIN_IF # goto FIN_IF ELSE: sub $t2, $t1, $t0 # c = b - a FIN_IF: addi $t2, $t2, 10 # c = c + 10
  38. 38. Ejemplo Código assembly para el siguiente código C: i = 0; sum = 0; do { sum = sum + a[i] * b[i]; i++; } while (i < 100) li $t0, 0 # i = 0; li $t1, 0 # $t1 = 0 (sum temporal) la $t2, SUM # $t2 = dirección de sum sw $t1, 0($t2) # sum = 0 LOOP: la $t3, A # $t3 = dirección a[0] la $t4, B # $t4 = dirección b[0] sll $t5, $t0, 2 # $t5 = i*4 add $t6, $t3, $t5 # $t6 = dirección a[i] lw $t7, 0($t6) # $t7 = a[i] add $t6, $t4, $t5 # $t6 = dirección b[i] lw $t8, 0($t6) # $t8 = b[i] mul, $t8, $t7, $t8 # $t8 = a[i]*b[i] add $t1, $t1, $t8 # $t1 = sum + a[i]*b[i] la $t2, SUM sw, $t1, 0($t2) # sum = sum + a[i] * b[i] add $t0, $t0, 1 # i = i + 1 slti $t7, $t0, 100 # i < 100? bne $t7, $zero, LOOP Vectores a y b y variable sum comienzan a partir de direcciones de memoria indicadas por rótulos A, B y SUM. Variable i asignada a registro $t0. ¿Posible optimizar código?
  39. 39. Ejemplo (optimizado) Código assembly para el siguiente código C: i = 0; sum = 0; do { sum = sum + a[i] * b[i]; i++; } while (i < 100) li $t0, 0 # i = 0; li $t1, 0 # $t1 = 0 (sum temporal) la $t3, A # $t3 = dirección a[0] la $t4, B # $t4 = dirección b[0] LOOP: add $t6, $t3, $t0 # $t6 = dirección a[i] lw $t7, 0($t6) # $t7 = a[i] add $t6, $t4, $t0 # $t6 = dirección b[i] lw $t8, 0($t6) # $t8 = b[i] mul, $t8, $t7, $t8 # $t8 = a[i]*b[i] add $t1, $t1, $t8 # $t1 = sum + a[i]*b[i] add $t0, $t0, 4 # i = i + 1 slti $t7, $t0, 400 # i < 100? bne $t7, $zero, LOOP la $t2, SUM sw, $t1, 0($t2) # sum = sum + a[i] * b[i] Vectores a y b y variable sum comienzan a partir de direcciones de memoria indicadas por rótulos A, B y SUM. Variable i asignada a registro $t0.
  40. 40. Otras instrucciones <ul><li>syscall </li></ul><ul><ul><li>Llamado a sistema: syscall (código en registro $v0) </li></ul></ul><ul><li>break </li></ul><ul><ul><li>Excepción: break #código </li></ul></ul><ul><li>nop </li></ul><ul><ul><li>No hace nada: nop </li></ul></ul><ul><li>eret (MIPS32, anterior rfe) </li></ul><ul><ul><li>Retorno de excepción: eret </li></ul></ul><ul><ul><li>Restaura registro de estado y máscara de interrupciones </li></ul></ul><ul><li>Instrucciones de coprocesadores y punto flotante </li></ul><ul><li>Instrucciones al TLB </li></ul><ul><li>Instrucciones para acceso no alineado a memoria </li></ul><ul><li>Pseudoinstrucciones </li></ul><ul><ul><li>Instrucciones assembly que no existen en el lenguaje de máquina </li></ul></ul><ul><ul><ul><li>Ejemplos: li, la </li></ul></ul></ul><ul><ul><ul><li>Ensamblador las traduce a una o más instrucciones de máquina (las que sí se pueden ejecutar) </li></ul></ul></ul>
  41. 41. Tabla resumen Syscall
  42. 42. Ensamblador MIPS <ul><li>Ventajas de lenguaje assembly versus lenguaje de máquina </li></ul><ul><ul><li>Mnemónicos </li></ul></ul><ul><ul><ul><li>Texto que representa operandos e instrucciones en vez de ceros y unos </li></ul></ul></ul><ul><ul><li>Definición de constantes y datos en memoria </li></ul></ul><ul><ul><li>Directivas al ensamblador </li></ul></ul><ul><ul><ul><li>Entregan información al ensamblador sobre cómo traducir el código assembly </li></ul></ul></ul><ul><ul><li>Rótulos (labels) </li></ul></ul><ul><ul><ul><li>Texto que representa valores constantes o direcciones de memoria </li></ul></ul></ul><ul><ul><li>Pseudoinstrucciones </li></ul></ul><ul><ul><ul><li>Instrucciones assembly que se traducen a unas pocas instrucciones de máquina </li></ul></ul></ul><ul><ul><ul><ul><li>Algunas utilizan registro $at como temporal </li></ul></ul></ul></ul><ul><li>Ensamblador realiza traducción de assembly a lenguaje de máquina </li></ul>
  43. 43. Rótulos <ul><li>Texto seguido de dos puntos (:) </li></ul><ul><ul><li>Entrega nombre a dirección de memoria </li></ul></ul><ul><ul><ul><li>Ejemplo </li></ul></ul></ul><ul><ul><li>También utilizado para datos </li></ul></ul><ul><ul><ul><li>Ejemplo: nombrar constantes </li></ul></ul></ul><ul><ul><ul><li>Ejemplo: nombrar direcciones de datos </li></ul></ul></ul><ul><ul><li>Pueden ser locales a módulo (archivo) o globales para todo el programa </li></ul></ul><ul><ul><ul><li>Ejemplo: para hacer símbolo MAIN global </li></ul></ul></ul>LOOP: add $4, $4, $2 j LOOP CONST = 2 … li $5, CONST .globl MAIN RES: .word 5 … la $t0, RES lw $t1, 0($t0)
  44. 44. Mapa de memoria <ul><li>Texto </li></ul><ul><ul><li>código del programa </li></ul></ul><ul><li>Heap </li></ul><ul><ul><li>Memoria dinámica </li></ul></ul><ul><ul><li>variables globales (estática) </li></ul></ul><ul><li>Stack </li></ul><ul><ul><li>Variables locales del procedimiento activo </li></ul></ul><ul><li>Reservado </li></ul><ul><ul><li>Estructuras del sistema operativo </li></ul></ul>
  45. 45. Algunas directivas al ensamblador .data Texto que sigue representa datos almacenados en el heap .text Texto que sigue representa instrucciones almacenadas en área de texto (código) .kdata Texto que sigue representa datos en área de datos del kernel (sistema operativo) .ktext Texto que sigue representa código en área de kernel .globl LABEL Rótulo LABEL es global (visible a todo el programa) .ascii str Almacenar string de texto str en ASCII sin un NULL al final .asciiz str Almacenar string de texto str en ASCII con un NULL (0) al final .word w1 … wn Almacenar n palabras (32b) en posiciones consecutivas de memoria .half h1 … hn Almacenar n medias palabras (16b) en posiciones consecutivas de memoria .byte b1 … bn Almacenar n bytes (8b) en posiciones consecutivas de memoria
  46. 46. Ejemplo .data TEXTOSINULL: .ascii “texto 1” TEXTOCONUL: .asciiz “texto 2” DATOS: .word 16 124 1000 .text .globl MAIN MAIN: la $8, TEXTOSINUL la $9, TEXTOCONUL la $10, DATOS lw $11, 0($10) lw $12, 4($10) lw $13, 8($10)
  47. 47. Procedimientos <ul><li>Son un componente importante en la estructura y modularidad de programas </li></ul><ul><li>Llamado y retorno requiere un protocolo del que llama y el que es llamado </li></ul><ul><li>Protocolo está basado en convención </li></ul>
  48. 48. Protocolo Procedimientos/funciones <ul><li>Cada máquina y compilador tiene su propio protocolo </li></ul><ul><li>Protocolo esta determinado por HW y SW </li></ul><ul><ul><li>Instrucción “jal” es HW </li></ul></ul><ul><ul><li>Usar registro $29 como $sp es SW (convención) </li></ul></ul><ul><li>Protocolo está determinado por una secuencia de pasos que se siguen por cada llamado y retorno </li></ul><ul><li>En RISC </li></ul><ul><ul><li>HW realiza instrucciones sencillas </li></ul></ul><ul><ul><li>SW controla (compilador/ensamblador) controla secuencia de instrucciones </li></ul></ul><ul><li>Registros utilizados </li></ul><ul><ul><li>$ra </li></ul></ul><ul><ul><li>$a0-$a3 </li></ul></ul><ul><ul><li>$v0-$v2 </li></ul></ul><ul><ul><li>$29 para puntero a stack </li></ul></ul><ul><li>Instrucciones </li></ul><ul><ul><li>jal, jr </li></ul></ul>
  49. 49. Ejemplo procedimiento simple int len; char[20] str; … len = strlen(str); … int strlen(char *str) { int len = 0; while (*str != 0) { str = str + 1; len = len + 1; } return len; } la $a0, str # $a0 = str jal STRLEN; # resultado retorna en $v0 STRLEN: li $v0, 0 # len = 0 WHILE: lb $t0, 0($a0) # $t0 = *str beq $t0, $zero, FIN_WHILE # if (*str == 0) goto FIN_W addi $a0, $a0, 1 # str = str + 1 addi $v0, $v0, 1 # len = len + 1 b WHILE # goto WHILE FIN_W: jr $ra # return len Utilizar convención estándar de uso de registros MIPS
  50. 50. Otro ejemplo procedimiento int i; int a[100], b[100] … res = punto(a, b, 100); … int prod_punto(int v1[], int v2[], int n) { int i = 0; suma = 0; do { suma = suma + v1[i] * v2[i]; i++; } while (i < n) return suma; } la $a0, A # $a0 = &(a[0]) la $a1, B # $a1 = &(b[0]) li $a2, 100 # $a2 = 100 jal PUNTO # resultado en $v0 la $t0, RES sw $v0, 0($t0) … PUNTO: li $t0, 0 # i = 0 li $v0, 0 # suma = 0 WHILE: sll $t1, $t0, 2 # $t1 = i*4 add $t2, $a0, $t1 # $t2 = &(v1[i]) lw $t3, 0($t2) # $t3 = v1[i] add $t2, $a1, $t1 # $t2 = &(v2[i]) lw $t4, 0($t2) # $t4 = v2[i] mult $t3, $t3, $t4 # $t3 = v1[i] * v2[i] add $v0, $v0, $t3 # suma = suma +… addi $t0, $t0, 1 # i = i + 1 slt $t3, $t0, $a2 # i < n? bne $t3, $zero, WHILE jr $ra
  51. 51. Qué hacer cuando los registros no son suficientes? <ul><li>Algunas preguntas </li></ul><ul><ul><li>Registros para paso de argumentos: $a0-$a3 </li></ul></ul><ul><ul><ul><li>¿Qué hacer cuando hay más de 4 argumentos? </li></ul></ul></ul><ul><ul><li>Retorno de valor: $v0-$v1 </li></ul></ul><ul><ul><ul><li>¿Qué hacer cuando el valor de retorno utiliza más de dos palabras (ej. una estructura)? </li></ul></ul></ul><ul><ul><li>Registros preservados por procedimiento invocado: $s0-$s7 </li></ul></ul><ul><ul><ul><li>¿Dónde debe respaldarlos el procedimiento? </li></ul></ul></ul><ul><ul><li>Registros preservados por procedimiento que invoca: $t0-$t9 </li></ul></ul><ul><ul><ul><li>¿Dónde respaldarlos? </li></ul></ul></ul><ul><ul><li>Dirección de retorno almacenada en: $ra </li></ul></ul><ul><ul><ul><li>¿Qué hacer con su contenido si procedimiento invoca a otro procedimiento? </li></ul></ul></ul><ul><ul><li>En general, ¿qué hacer cuando se nos acaban los registros que estamos utilizando? </li></ul></ul>
  52. 52. Datos locales y procedimientos recursivos <ul><li>Respuesta: el único lugar donde pueden almacenarse estos datos es la memoria </li></ul><ul><li>Alternativa 1: almacenarlos en área de memoria global asociada al procedimiento </li></ul>PROC1: move $t0, $a0 … la $s0, PROC1_MEM sw $t0, 0($s0) sw $ra, 4($s0) jal PROC2 lw $t0, 0($s0) lw $ra, 4($s0) … jr $ra Ahora PROC2 puede sobreescribir $t0 y $ra sin problemas PROC1_MEM $t0 $ra Problema: ¿Qué pasa si PROC1 es recursivo? Direcciones de memoria
  53. 53. Procedimientos y stacks <ul><li>Alternativa 2 : definir un área de memoria asociada a cada activación de cada procedimiento </li></ul><ul><ul><li>Estructura dinámica de llamado a procedimientos asemeja una pila (stack) </li></ul></ul><ul><ul><ul><li>Retornan en el sentido inverso en el que fueron invocados </li></ul></ul></ul><ul><ul><li>Memoria para almacenamiento de datos locales también se estructura como un stack </li></ul></ul>A A A A A B B B C A: call B B: call C C: ret ret … …
  54. 54. Stacks de memoria <ul><li>Almacenan ambientes asociados a procedimientos anidados (marco de activación) </li></ul><ul><ul><li>Dirección de retorno </li></ul></ul><ul><ul><li>Argumentos </li></ul></ul><ul><ul><li>Variables locales </li></ul></ul><ul><ul><li>Valor de retorno </li></ul></ul><ul><ul><li>Registros salvados por el procedimiento </li></ul></ul>
  55. 55. Soporte para stacks <ul><li>Stack pointer (SP) </li></ul><ul><ul><li>Apunta al tope del stack </li></ul></ul><ul><ul><li>Usado para agregar y sacar datos a stack </li></ul></ul><ul><li>Frame pointer (FP) </li></ul><ul><ul><li>Apunta a base del bloque de activación (stack frame) </li></ul></ul><ul><ul><li>Usado para accesar variables locales y argumentos sin removerlos del stack </li></ul></ul><ul><li>Operaciones </li></ul><ul><ul><li>PUSH </li></ul></ul><ul><ul><li>POP </li></ul></ul><ul><ul><li>CALL </li></ul></ul><ul><ul><li>RETURN </li></ul></ul><ul><li>Soporte ISA para stacks </li></ul><ul><ul><li>En el lenguaje de máquina: VAX, Intel, registros e instrucciones específicas </li></ul></ul><ul><ul><li>Por convención de software: MIPS </li></ul></ul><ul><ul><ul><li>Soporte mínimo: jal, jr </li></ul></ul></ul>Argumentos Registros salvados por el llamado Variables locales Evaluación de expresiones (dinámico) FP SP
  56. 56. Ejemplo: Cadena de llamados Estructura de código <ul><li>p1(…) </li></ul><ul><li>{ </li></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>p2(); </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><li>} </li></ul><ul><li>p2(…) </li></ul><ul><li>{ </li></ul><ul><ul><li>• • • </li></ul></ul><ul><ul><li>p3(); </li></ul></ul><ul><ul><li>• • • </li></ul></ul><ul><ul><li>p3(); </li></ul></ul><ul><ul><li>• • • </li></ul></ul><ul><li>} </li></ul><ul><li>p3(…) </li></ul><ul><li>{ </li></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>p3(); </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><li>} </li></ul>p1 p2 p3 p3 p3 Cadena de llamados <ul><ul><li>Procedimiento p3 es recursivo </li></ul></ul>p3
  57. 57. p1 • • • p1 Cadena de llamados <ul><li>p1(…) </li></ul><ul><li>{ </li></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>p2(); </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><li>} </li></ul>Operación del stack Stack Pointer $sp Frame Pointer $fp
  58. 58. Operación del stack p1 p2 • • • p1 p2 Cadena de llamados <ul><li>p2(…) </li></ul><ul><li>{ </li></ul><ul><ul><li>• • • </li></ul></ul><ul><ul><li>p3(); </li></ul></ul><ul><ul><li>• • • </li></ul></ul><ul><ul><li>p3(); </li></ul></ul><ul><ul><li>• • • </li></ul></ul><ul><li>} </li></ul>Stack Pointer $sp Frame Pointer $fp
  59. 59. Operación del stack p1 p2 p3 • • • p1 p2 p3 Cadena de llamados <ul><li>p3(…) </li></ul><ul><li>{ </li></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>p3(); </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><li>} </li></ul>Stack Pointer $sp Frame Pointer $fp
  60. 60. Operación del stack p1 p2 p3 • • • p1 p2 p3 Cadena de llamados <ul><li>p3(…) </li></ul><ul><li>{ </li></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>p3(); </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><li>} </li></ul>p3 p3 Stack Pointer $sp Frame Pointer $fp
  61. 61. Operación del stack p1 p2 p3 • • • p1 p2 p3 Cadena de llamados <ul><li>p3(…) </li></ul><ul><li>{ </li></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>p3(); </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><li>} </li></ul>p3 p3 p3 p3 Stack Pointer $sp Frame Pointer $fp
  62. 62. Operación del stack p1 p2 p3 • • • p1 p2 p3 Cadena de llamados <ul><li>p3(…) </li></ul><ul><li>{ </li></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>p3(); </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><li>} </li></ul>p3 p3 amI Stack Pointer $sp Frame Pointer $fp
  63. 63. Operación del stack p1 p2 p3 • • • p1 p2 p3 Cadena de llamados <ul><li>p3(…) </li></ul><ul><li>{ </li></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>p3(); </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><li>} </li></ul>p3 p3 Stack Pointer $sp Frame Pointer $fp
  64. 64. Operación del stack p1 p2 • • • p1 p2 Call Chain <ul><li>p2(…) </li></ul><ul><li>{ </li></ul><ul><ul><li>• • • </li></ul></ul><ul><ul><li>p3(); </li></ul></ul><ul><ul><li>• • • </li></ul></ul><ul><ul><li>p3(); </li></ul></ul><ul><ul><li>• • • </li></ul></ul><ul><li>} </li></ul>p3 p3 p3 Stack Pointer $sp Frame Pointer $fp
  65. 65. Operación del stack p1 p2 p3 • • • p1 p2 Cadena de llamados <ul><li>p3(…) </li></ul><ul><li>{ </li></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><li>} </li></ul>p3 p3 p3 p3 Stack Pointer $sp Frame Pointer $fp
  66. 66. Operación del stack p1 p2 • • • p1 p2 Cadena de llamados <ul><li>p2(…) </li></ul><ul><li>{ </li></ul><ul><ul><li>• • • </li></ul></ul><ul><ul><li>p2(); </li></ul></ul><ul><ul><li>• • • </li></ul></ul><ul><ul><li>p2(); </li></ul></ul><ul><ul><li>• • • </li></ul></ul><ul><li>} </li></ul>p3 p3 p3 p3 Stack Pointer $sp Frame Pointer $fp
  67. 67. Operación del stack <ul><li>p1(…) </li></ul><ul><li>{ </li></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>p2(); </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><ul><li>• </li></ul></ul><ul><li>} </li></ul>p1 • • • p1 p2 Cadena de llamados p3 p3 p3 p3 Stack Pointer $sp Frame Pointer $fp
  68. 68. Stack (Pila) de Programa <ul><li>Cada programa en ejecución (proceso) tiene un stack </li></ul><ul><li>Stack: estructura de datos dinámica accesada en LIFO </li></ul><ul><li>Stack de programa automáticamente asignada por el SO </li></ul><ul><li>Al comienzo del proceso el registro $sp ($29 en MIPS) es automáticamente cargado a un punto de la primera entrada vacía al tope del stack </li></ul><ul><ul><li>Después de eso queda a manos del programador el uso del stack </li></ul></ul><ul><li>Por convención, el stack crece hacia direcciones más bajas </li></ul><ul><ul><li>Para asignar una nueva entrada (al hacer push), decrementar $sp </li></ul></ul><ul><ul><li>Para liberar espacio en el tope del stack (al hacer pop), incrementar $sp </li></ul></ul>
  69. 69. Operación push <ul><li>Push agrega un item en el tope del stack </li></ul><ul><ul><li>Una instrucción para manipular dato : “sw $6, 0($sp)” </li></ul></ul><ul><ul><li>Una instrucción para ajustar el puntero al stack : “subu $sp, $sp, 4” </li></ul></ul>antes después 46 -72 ??? 46 -72 127 ??? 8($sp) 4($sp) $sp 12($sp) 8($sp) 4($sp) $ sp 127 $6 127 $6
  70. 70. Operación pop <ul><li>Pop remueve un item del tope del stack y lo almacena en un registro </li></ul><ul><ul><li>Una instrucción para ajustar el puntero a stack : “addu $sp, $sp, 4” </li></ul></ul><ul><ul><li>Una instrucción para manipular el dato : “lw $6, 0($sp)” </li></ul></ul>antes 46 -72 127 46 -72 127 ??? 8($sp) 4($sp) $ sp 12($sp) 8($sp) 4($sp) $sp 127 $6 453 $6 Pasa a ser basura despúes
  71. 71. Requerimientos llamados a procedimiento <ul><li>El que llama debe pasar la dirección de retorno al que es llamado (procedimiento) </li></ul><ul><li>El que llama debe pasar los parámetros al procedimiento </li></ul><ul><li>El que llama debe guardar el contenido de los registros que podrían ser usados por el procedimiento </li></ul><ul><li>El procedimiento debe guardar la dirección de retorno (si es que llama a otro procedimiento o el mismo si es recursivo) </li></ul><ul><li>El procedimiento debe proporcionar almacenamiento de stack para su propio uso </li></ul>
  72. 72. Mecanismo <ul><li>Registros son usados </li></ul><ul><ul><li>Para pasar dirección de retorno en $ra </li></ul></ul><ul><ul><ul><li>Jal target </li></ul></ul></ul><ul><ul><li>Para pasar parámetros ($a0 … $a3, a lo más 4) </li></ul></ul><ul><ul><li>Mantener el valor de $sp </li></ul></ul><ul><ul><li>Retornando valores de función en $v0, $v1 </li></ul></ul><ul><li>Stacks son usados para </li></ul><ul><ul><li>Salvar registros para ser usados por procedimientos </li></ul></ul><ul><ul><li>Salvar información acerca del que llama (dirección de retorno) </li></ul></ul><ul><ul><li>Pasar parámetros si se necesita </li></ul></ul><ul><ul><li>Asignando datos locales para el procedimiento llamado </li></ul></ul>
  73. 73. Convención uso de registros Dirección de retorno de función $ra $31 Puntero a la base del stack (Frame Pointer) $fp $30 Puntero al tope del stack (Stack Pointer) $sp $29 Puntero al heap (segmento datos global) $gp $28 Reservados al O.S. $k0-$k1 $26-$27 Temporales no salvados al llamar función $t8-$t9 $24-$25 Temporales salvados al llamar función $s0-$s7 $16-$23 Temporales no salvados al llamar función $t0-$t7 $8-$15 Argumentos en llamada función $a0-$a3 $4-$7 Evaluación expresiones y resultado funciones $v0-$v1 $2-$3 Reservado para temporal del ensamblador $at $1 Cero $zero $0 Uso Nombre Registro
  74. 74. Tareas del que llama y procedimiento llamado en CALL <ul><li>El que llama </li></ul><ul><ul><li>Salva contenido de registros volatiles ($t0…$t9) teniendo contenidos que deben ser guardados </li></ul></ul><ul><ul><li>Poner a lo más 4 argumentos en $a0…$a3 </li></ul></ul><ul><ul><li>Si hay más de 4 argumentos, poner el resto en el stack </li></ul></ul><ul><ul><li>Llamar a jal instrucción </li></ul></ul><ul><li>Procedimiento </li></ul><ul><ul><li>Salva $ra en stack </li></ul></ul><ul><ul><li>Salva cualquier registro no volátil ($s0…$s7) que se usará </li></ul></ul>
  75. 75. Tareas del que llama y procedimiento llamado en RETURN <ul><li>Procedimiento </li></ul><ul><ul><li>Restaura cualquier registro no volátil ($s0…$s7) que ha usado </li></ul></ul><ul><ul><li>Restaura $ra </li></ul></ul><ul><ul><li>Pone resultados de función en $v0, $v1 </li></ul></ul><ul><ul><li>Retorna al que llama con instrucción “jr $ra” </li></ul></ul><ul><li>El que llama </li></ul><ul><ul><li>Restaura cualquier registro volátil que ha salvado </li></ul></ul><ul><ul><li>Examina $v0 y $v1 si lo necesita </li></ul></ul>
  76. 76. Ejemplo de un CALL <ul><li>Asumir que los argumentos en $t0 y $t3 y que se desea salvar los contenidos en $t6 y $t7 </li></ul><ul><ul><li>move $a0,$t0 # argumento 1 en $a0 </li></ul></ul><ul><ul><li>move $a1,$t3 # argumento 2 en $a1 </li></ul></ul><ul><ul><li>subu $sp,$sp,8 #espacio para 2 temps en stack </li></ul></ul><ul><ul><li>sw $t6,8($sp) #salvar $t6 en stack </li></ul></ul><ul><ul><li>sw $t7,4($sp) #salvar $t7 en stack </li></ul></ul><ul><ul><li>jal target </li></ul></ul><ul><li>Asumir que procedimiento no necesita salvar registros </li></ul><ul><ul><li>target: sw $ra,0($sp) #salva dirección de retorno </li></ul></ul><ul><ul><li>subu $sp,$sp,4 # en stack </li></ul></ul>
  77. 77. Ejemplo RETURN <ul><li>El procedimiento pondrá valores de retorno en $v0, $v1 </li></ul><ul><ul><li>addu $sp,$sp,4 #pop </li></ul></ul><ul><ul><li>lw $ra,0($sp) #dir de retorno en $ra </li></ul></ul><ul><ul><li>jr $ra #para el que llama </li></ul></ul><ul><li>El que llama restaura $t6 y $t7 y ajusta stack </li></ul><ul><ul><li>lw $t6,8($sp) </li></ul></ul><ul><ul><li>lw $t7,4($sp) </li></ul></ul><ul><ul><li>addu $sp,$sp,8 </li></ul></ul>
  78. 78. Ejemplo: Factorial recursivo int factorial(int n) { if (n == 0) return 1; else return n * factorial(n-1); } FACT: bne $a0, $0, L1 # saltar si n != 0 li $v0, 1 # retornar 1 jr $ra L1: addiu $sp, $sp, -12 # tamaño del nuevo stack es 12 bytes sw $fp, 0($sp) # almacenar $fp en el stack sw $ra, 4($sp) # almacenar $ra en el stack addiu $fp, $sp, 8 # $fp apunta al principio del stack sw $a0, 0($fp) # almacenar n en el stack addiu $a0, $a0, -1 # n - 1 jal FACT # resultado en $v0 lw $a0, 0($fp) # recuperar n lw $ra, 4($sp) # recuperar direccion de retorno lw $fp, 0($sp) # recuperar $fp addiu $sp, $sp, 12 # restaurar stack original $sp mul $v0, $v0, $a0 # n * fact(n-1) jr $ra Mostrar ejemplos usando fp y no usando fp, usando ConTEXT Ejercicio: hacer dibujo con marcos de activación y cadena de llamados
  79. 79. Excepciones <ul><li>Condiciones especiales que cambian el flujo de ejecución normal del programa </li></ul><ul><li>Tipos de excepciones </li></ul><ul><ul><li>Interrupción </li></ul></ul><ul><ul><ul><li>Generada en forma externa al procesador, típicamente por dispositivo de E/S como interfaz de red o disco </li></ul></ul></ul><ul><ul><li>Trap </li></ul></ul><ul><ul><ul><li>Efecto colateral (implícito o explícito) de ejecución de instrucción </li></ul></ul></ul><ul><ul><ul><ul><li>Ej. División por cero, acceso ilegal a memoria, instrucción inválida, syscall, break. </li></ul></ul></ul></ul>
  80. 80. Atención de excepciones <ul><li>Típicamente </li></ul><ul><ul><li>Almacenar estado del procesador (PC, registro de condición, máscara de interrupciones, etc.) </li></ul></ul><ul><ul><li>Transferir control al sistema operativo </li></ul></ul><ul><ul><li>Pasar a modo de ejecución supervisor </li></ul></ul><ul><ul><li>Sistema operativo atiende excepción, restaura el estado y retorna al programa de usuario </li></ul></ul>
  81. 81. Atención de excepciones en MIPS <ul><li>Registros que controlan estado de procesador </li></ul><ul><ul><li>Parte del coprocesador 0 </li></ul></ul><ul><ul><li>Accesados mediante instrucciones mfc0 y mtc0 </li></ul></ul>
  82. 82. Registro Causa
  83. 83. Registro de estado <ul><li>Excepciones e interrupciones causan al procesador MIPS saltar a una porción de código a la dirección 0x80000180 (en modo kernel) llamado exception handler o manejador de interrupciones </li></ul><ul><li>Este código examina causa de excepción y salta al punto apropiado de la rutina de atención de la excepción que ocurrió ( en el SO). </li></ul>

×