Upload
stefano-salvatori
View
2.005
Download
3
Tags:
Embed Size (px)
Citation preview
Estructura de un Sistema Computacional
CPU
Memoria
Módulosde
Salida
Secciónde
Datos
Sw
Secciónde
Control
Módulosde
Entrada Fwy
Hw
Compilador oIntérprete
Interfaz de SwISA
Sistema Operativo
Aplicaciones
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
Interfaz HW/SW
swap (int v[], int k){
int tmp;tmp=v[k];v[k]=v[k+1];v[k+1]=tmp;
}swap: muli $2,$5,4
add $2,$4,$2 lw $15,0($2) lw $16,4($2) sw $16,0($2) sw $15,4($2) jr $31
Compilador C
Ensamblador
000100 00101 00010 0000000000000100000000 00100 00010 00010 00000 000001100011 00010 01111 0000000000000000100011 00010 10000 0000000000000100101011 00010 10000 0000000000000000101011 00010 01111 0000000000000100000000 11111 00000 00000 00000 001000
Programa C
Programa Assembler
Programa Lenguaje Máquina
InstruccionesDirectas a la CPU
Convenciones
UNIX P.c : archivo fuente en
lenguaje C P.s : archivo fuente en
lenguaje ensamblador P.o : archivo objeto P.a : biblioteca
estáticamente linkeada P.so : biblioteca
dinámicamente linkeada
a.out : archivo ejecutable por defecto
MS-DOS P.C : archivo fuente en
lenguaje C P.ASM : archivo fuente
en lenguaje ensamblador
P.OBJ : archivo objeto P.LIB : biblioteca
estaticamente linkeada P.DLL : biblioteca
dinámicamente linkeada
P.EXE: archivo ejecutable
Qué es una instrucción?
Comando que le dice a la CPU que operación realizar Mediante código de operación
Todas las instrucciones están codificadas Donde se encuentran los operandos necesarios para ejecutar la
operación ISA de una instrucción especifica
Código de operación Cuántos operandos son necesarios, tipos, tamaños, ubicación
Operandos Registros (enteros, punto flotante, PC) Dirección de memoria Constantes
Ejecución de instrucción de máquina
CPU ejecuta instrucciones de un programa ciclo
Instrucciones especifican operaciones sobre operandos y generan resultados
Datos pueden encontrarse en memoria (RAM, ROM) o en registros internos al procesador
Instrucciones pueden también modificar el flujo de control (saltos, llamadas a procedimiento)
Instrucciones pueden crear excepciones
LeerInstrucción
Decodificar
LeerOperandos
EjecutarInstrucción
AlmacenarResultados
Cálculo SgteInstrucción
Arquitectura de Conjunto de Instrucciones ISA
Visión del programador de bajo nivel o del compilador Elementos que definen la ISA
Operaciones (instrucciones) suma, multiplicación, saltos, entrada/salida
Tipos de datos Entero, punto flotante, strings
Número y forma de acceder a operandos y resultados 0,1,2,3 operandos, residentes en memoria o registros internos
Formato (codificación) de instrucciones y datos Complemento a 2, punto flotante IEEE
Espacio de memoria y número de registros Condiciones excepcionales
División por cero, excepción de memoria virtual, llamada a sistema operativo
MIPS
Una familia de procesadores 32 bits : R2000/3000 64 bits : R4000/4400, R10000
Partió como proyecto de investigación en Stanford y luego formó compañía MIPS, que posteriormente compró Silicon Graphics
Proviene de máquinas DEC MIPS es RISC Actualmente usados en mercados de sistemas encrustrados
o embebidos Routers CISCO, modems cable (modula señales de
comunicación sobre infraestructura de TV cable), impresoras laser, Sony playstation 2, computadores handheld
http://www.mips.com/content/Markets/MIPSBased/content_html
Aplicaciones del procesador MIPS
Almacenamiento en MIPSCPU
$0
$1
.
.
.
$31
HI
LO
PC
Mult/DivEnteros
ALU
Coprocesador 1
$f0
$f1
.
.
.
$f31
AritméticaFP
Coprocesador 0
Cause
Status
BadVAddress
EPC
Memoria
Registros MIPS Registros de propósito general
Un banco de registro de 32 registros de 32 bits direccionados $0, $1,…, $31 Aritmética entera y lógica cálculo de direcciones, operaciones de
propósito específico como Puntero al Stack (pila) Un banco de registros punto flotante. Registros de 32 bits
direccionados $f1, $f2,…$f31 usados para aritmética punto flotante
Registros de propósito específico 2 registros de 32 bits (HI, LO) usados para multiplicación y
división Un registro Contador de Programas (PC) Registro de estado (coprocesador 0) almacena causa de
excepción datos relacionados a excepción ISA con registros generales también son llamadas
Ortogonales Operaciones son independientes de los registros
ISA MIPS define Convención Software para uso de registros No es obligatoria, no es forzada por hardware
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
MIPS=RISC = Arquitectura load/store
ALU opera sólo en operandos que están en registros 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)
Implica que variables deben estar “loaded” en registros (si vienen de la memoria) antes de ejecutar otro tipo de instrucciones
Las únicas instrucciones que accesan la memoria son del tipo load/store Se necesitan instrucciones explícitas para realizar
operaciones de “load” y “store” Resultados obtenidos de otras operaciones deben ser
“stored” en memoria
Ejemplo
Sentencia expresada en un lenguaje de programación de alto nivel x = y + z w = x + y
Se traduce en lenguaje assembly (ensamblador) como (asumiendo operandos están en memoria) load y en registro ry load z en registro rz rx <- ry + rz store rx en x, no borra el resultado en rx rt <- rx + ry store rt en w
Programando en lenguaje ensamblador
Usar muchos comentarios para describir lo que se esta haciendo
Usar words en lugar de bytes en lo posible
La siguiente dirección a dato expresado en words es dirección + 4
Direcciones de words son divisibles por 4
Tipos de instrucciones en MIPS
Aritméticas Operaciones con enteros (con y sin signo) Operaciones con punto flotante
Lógicas y de desplazamiento Ands, ors, entre otros Desplazamiento de bits (izquierda, derecha)
Load/store Variables son cargadas en registros (load)
Desde memoria a registros o constantes a registros Resultados se graban en memoria (store)
Comparación de valores en registros Saltos condicionales (branches) y absolutos (jumps)
Manipulan control de flujo Incluyen llamados a procedimientos y retornos
Aritmética entera
Números pueden ser con o sin signo Instrucciones aritméticas (+,-,/,*) existen
para ambos tipos de enteros (diferenciado por código de operación) add, addu, sub, subu addi, addiu, subi, subiu mult, multu, div, divu
Números con signo son representados en complemento a 2 En caso de overflow se genera excepción
Notación en SPIM
Código operación rd, rs, rt Instrucciones aritmeticas, lógicas, comparaciones
Código operación rt, rs, immediato Instrucciones aritméticas, lógicas, load/store, saltos
condicionales Código operación immediato
Instrucciones de salto absoluto Donde:
rd siempre es el registro destino rs siempre es el registro fuente (de sólo lectura) rt puede ser fuente o destino depende del código de
operación Immediato es una constante de 16 bits (con o sin signo)
Instrucciones aritméticas en SPIM
No confundirlo con la codificación de instrucciones que se verá pronto
# rd = rs - rtrd, rs, rtsub
# rt = rs + immedrt, rs, immediatoaddi
# rd = rs + rtrd, rs, rtadd
ComentariosOperandosCódigo Operación
Instrucciones aritméticas
add $1,$2,$3 #$1 = $2 + $3. Posible overflowsub $1,$2,$3 #$1 = $2 – $3. Posible overflowaddi $1,$2,100 #$1 = $2 + 100. Posible overflowaddu $1,$2,$3 #$1 = $2 + $3. Suma sin signo sin overflowsubu $1,$2,$3 #$1 = $2 – $3. Resta sin signo sin overflowaddiu $1,$2,100 #$1 = $2 + 100. Suma sin signo sin overflowmult $2,$3 #HI, LO = $2 x $3multu$2,$3 #HI, LO = $2 x $3. Producto sin signodiv $2,$3 #LO = $2 ÷ $3 (cuociente)
#HI = $2 mod $3 (resto)divu $2,$3 #LO = $2 ÷ $3 (cuociente sin signo)
#HI = $2 mod $3 (resto)abs $1, $2 #$1 = |$2|. Valor absoluto
Ejemplos
Add $8,$9,$10 #$8=$9+$10Add $t0,$t1,$t2 #$t0=$t1+$t2Sub $s2,$s1,$s0 #$s2=$s1-$s0
Addi $a0,$t0,20 #$a0=$t0+20Addi $a0,$t0,-20 #$a0=$t0-20
Addi $t0,$0,0 #clear $t0Sub $t5,$0,$t5 #$t5 = -$t5
Instrucciones lógicas
and $1,$2,$3 #$1 = $2 && $3or $1,$2,$3 #$1 = $2 || $3xor $1,$2,$3 #$1 = ~($2 || $3)nor $1,$2,$3 #$1 = ~($2 || $3)andi $1,$2,10 #$1 = $2 && 10ori $1,$2,10 #$1 = $2 || 10xori $1, $2,10 #$1 = ~$2 && ~10sll $1,$2,10 #$1 = $2 << 10. Desplazamiento lógicosrl $1,$2,10 #$1 = $2 >> 10. Desplazamiento lógicosra $1,$2,10 #$1 = $2 >> 10. Desplazamiento aritméticosllv $1,$2,$3 #$1 = $2 << $3. Desplazamiento lógicosrlv $1,$2, $3 #$1 = $2 >> $3. Desplazamiento lógicosrav $1,$2, $3 #$1 = $2 >> $3. Desplazamiento aritmético
Movimiento entre registros
move $2,$3 # $2 $3 (PseudoInstrucción)mflo $2 # $2 LO. Copia LO en $2mfhi $2 # $2 HI. Copia HI en $2mtlo $2 # LO $2. Copia en LO $2mthi $2 # $2 HI. Copia en HI $2lui $3, 500 # $3 500 * 216. Carga el valor
# constante de 16b en la parte# más significativa de
$3mfc0 $1, $epc # $1 dirección de instrucción que
# causó excepción
Acceso a memoria
Mueven datos entre registros y memoria Modo de direccionamiento único
base + desplazamiento Base: contenido de registro Desplazamiento: constante de 16 bits Load
lw rt,rs,offset #rt = Memory[rs+offset]lw $1, 100($2) # $1 Mem[$2 + 100]
Storelw rt,rs,offset #Memory[rs+offset]=rtsw $1, 100($2) # $1 -> Mem[$2 + 100]
Instrucciones load/store
sw $3, 500($2) # Mem(500+$2) $3. Almacena 32bsh $3, 500($2) # Mem(500+$2) $3. Almacena 16bsb $3, 500($2) # Mem(500+$2) $3. Almacena 8b
lw $3, 500($2) # $3 Mem(500+$2). Carga 32b lh $3, 500($2) # $3 Mem(500+$2). Carga 16b lhu $3, 500($2) # $3 Mem(500+$2).
# Carga 16b sin signolb $3, 500($2) # $3 Mem(500+$2). Carga 8b
la $3, Label # $3 Address. Carga la dirección # efectiva asociada a Label en $3
Dirección efectiva: número que indica dirección del operando en memoria
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, LABEL16bsuperiores
# ori $4, $4, LABEL16binferiores
bgt $4, CTE, LABEL # if ($4 > CTE) goto LABEL# slti $at, $4, CTE+1# beq $at, $zero, LABEL
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 ala $v1, DIR_B # cargar dirección de b
lw $t0, 0($v0) # leer alw $t1, 0($v1) # leer b
mul $t2, $t0, $t1 # t2 = a * b
la $v2, DIR_ACUM # cargar dirección de acumlw $t3, 0($v2) # leer acum
add $t3, $t3, $t2 # $t3 = acum + a * bsw $t3, 0($v2) # guardar acum
10
2
DIR_A
DIR_B
DIR_ACUM50
Memoria
$v0
$v1
$v2
$t0
$t1
$t2
$t31000
1012
10
2
201024
5070
70
1000100410081012101610201024
a
b
acum
Ejemplotypedef 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 c1la $v1, DIR_C2 # cargar dirección de c2
lw $t0, 0($v0) # leer c1.xlw $t1, 0($v1) # leer c2.xsub $t2, $t1, $t0 # t2 = c2.x – c1.xabs $t3, $t2 # t3 = abs(c2.x – c1.x)
lw $t0, 4($v0) # leer c1.ylw $t1, 4($v1) # leer c2.ysub $t2, $t1, $t0 # t2 = c2.y – c1.yabs $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 distsw $t3, 0($v0) # dist = abs(c2.x – c1.x) +
# abs(c2.y – c1.y)
c1.xc1.y
c2.xc2.y
Direcciones de memoria
DIR_C1
DIR_C1 + 4
DIR_C2
DIR_C2 + 4
DIR_DIST dist
Memoria
Ejecución condicional de instrucciones
Permiten ejecutar partes de un programa sólo si se cumple una determinada condición Ej. Estructuras tipo if-else, for, while, switch-case Típicamente saltos, pero también escritura a
registro ¿Cómo especificar la condición?
Comparación en la instrucción bgt r1, r2, ADDR # if r1 > r2 goto ADDR
Registro de condición (MIPS) cmp r1, r2, r3 # r3 = signo (r1-r2)
bgtz r1, ADDR # if r1 > 0 goto ADDR
Instrucciones ISA MIPS
Instrucciones de comparación Evalúa condición entre dos operandos
Resultado es VERDADERO o FALSO Utilizan registro de condición
Resultado de comparación se almacena en registro destino FALSO regDest = 0 VERDADERO regDest = 1
Ejemplo:add $1, $2, $3slt $4, $1, $0 # if $1 < $0 then $4 = 1
# else #4 = 0
Algunas instrucciones de comparación
slt $1,$2,$3 # if ($2 < $3) $1= 1 else $1 = 0sltu $1,$2,$3 # if ($2 < $3) $1 = 1 else $1 = 0 (sin signo)slti $1, $2, 100 # if ($2 < 100) $1 = 1 else $1 = 0sltiu $1, $2, 100 # if ($2 < 100) $1 = 1 else $1 = 0 (sin signo)
Pseudoinstrucciones (se traducen en más de una instrucción de máquina):
seq $1, $2, $3 $if ($2 == $3) $1 = 1 else $1 = 0sne $1, $2, $3 $if ($2 != $3) $1 = 1 else $1 = 0sgt $1, $2, $3 $if ($2 > $3) $1 = 1 else $1 = 0sge $1, $2, $3 $if ($2 >= $3) $1 = 1 else $1 = 0sle $1, $2, $3$if ($2 <= $3) $1 = 1 else $1 = 0
Y otras…
Instrucciones de salto MIPS
Saltos condicionalesbeq $1,$2,CLabel # if ($1==$2) goto CLabel ;bne $1,$2,CLabel # if ($1!=$2) goto CLabel ;bgez $1, Clabel # if ($1 >=0) goto Clabelbgtz, $1, Clabel # if ($1 >0) goto Clabelblez, $1, Clabel # if ($1<=0) goto Clabelbltz $1, Clabel # if ($1<0) goto CLabel
bge $1,$2,CLabel # if ($1>=$2) goto CLabel ;bgt $1,$2,CLabel # if ($1>$2) goto CLabel ;bgtu $1,$2,CLabel # if ($1>$2) goto CLabel ;
# Comparación sin signoble $1,$2,CLabel # if ($1<=$2) goto CLabel ;blt $1,$2,CLabel # if ($1<$2) goto CLabel ;bltu $1,$2,CLabel # if ($1<$2) goto CLabel ;
# Comparación sin signo
Instrucciones de transferencia de control
Registro de contador de programa Program Counter (PC) Almacena dirección de siguiente instrucción a ejecutar Por defecto, instrucción físicamente siguiente a la actual (PC PC +
4) Modificación del flujo de control de un programa
Tipos de salto (especificación de dirección destino) Absoluto: instrucción especifica directamente dirección destino Relativo: instrucción especifica desplazamiento respecto de
instrucción actual Tipos de salto (ejecución condicional)
Incondicional: salto se realiza de todas formas Condicional: salto se realiza sólo si se cumple una condición
La mayoría de las ISA usan dos tipos de salto jump: absoluto e incondicional branch: relativo y condicional
Saltos
Otros tipos de salto Salto a procedimiento: almacena dirección de
retorno Retorno de procedimiento: retorna a instrucción
siguiente a la que hizo el salto a procedimiento Llamado a sistema: salta a dirección predeterminada
y pasa a modo supervisor Retorno de excepción o llamado a sistema: retorna
a instrucción que provocó excepción o llamado a sistema, y restaura modo usuario
Instrucciones de salto MIPS
Saltos absolutosj CLabel # PC CLabel
Saltos a procedimientojal CLabel # $ra PC; PC CLabel;bgezal $1, CLabel # if ($1>=0) $ra = PC; PC = Clabel• Recordar que, durante la ejecución de una instrucción, PC contiene la
dirección de la siguiente instrucción a ejecutar• $ra = $31
Saltos indexados
jr $ra # PC $ra
jalr $1, $2 # $2 PC + 4; PC $1
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 = 10li $t1, 5 # b = 5
sle $t3, $t0, $t1 # a <= b ?bgtz $t3, ELSE # if a <= b goto ELSE
sub $t2, $t0, $t1 # c = a - bj FIN_IF # goto FIN_IF
ELSE: sub $t2, $t1, $t0 # c = b - a
FIN_IF: addi $t2, $t2, 10 # c = c + 10
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 sumsw $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*4add $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, SUMsw, $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 apartir de direcciones de memoria indicadaspor rótulos A, B y SUM. Variable i asignada a registro $t0.
¿Posible optimizar código?
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, SUMsw, $t1, 0($t2) # sum = sum + a[i] * b[i]
Vectores a y b y variable sum comienzan apartir de direcciones de memoria indicadaspor rótulos A, B y SUM. Variable i asignada a registro $t0.
Otras instrucciones
syscall Llamado a sistema: syscall (código en registro $v0)
break Excepción: break #código
nop No hace nada: nop
eret (MIPS32, anterior rfe) Retorno de excepción: eret Restaura registro de estado y máscara de interrupciones
Instrucciones de coprocesadores y punto flotante Instrucciones al TLB Instrucciones para acceso no alineado a memoria Pseudoinstrucciones
Instrucciones assembly que no existen en el lenguaje de máquina Ejemplos: li, la Ensamblador las traduce a una o más instrucciones de máquina
(las que sí se pueden ejecutar)
Tabla resumen Syscall
Ensamblador MIPS
Ventajas de lenguaje assembly versus lenguaje de máquina Mnemónicos
Texto que representa operandos e instrucciones en vez de ceros y unos
Definición de constantes y datos en memoria Directivas al ensamblador
Entregan información al ensamblador sobre cómo traducir el código assembly
Rótulos (labels) Texto que representa valores constantes o direcciones de
memoria Pseudoinstrucciones
Instrucciones assembly que se traducen a unas pocas instrucciones de máquina Algunas utilizan registro $at como temporal
Ensamblador realiza traducción de assembly a lenguaje de máquina
Rótulos Texto seguido de dos puntos (:)
Entrega nombre a dirección de memoria Ejemplo
También utilizado para datos Ejemplo: nombrar constantes
Ejemplo: nombrar direcciones de datos
Pueden ser locales a módulo (archivo) o globales para todo el programa Ejemplo: para hacer símbolo MAIN global
LOOP: add $4, $4, $2j LOOP
CONST = 2…
li $5, CONST
.globl MAIN
RES: .word 5…
la $t0, RESlw $t1, 0($t0)
Mapa de memoria
Texto código del programa
Heap Memoria dinámica variables globales
(estática) Stack
Variables locales del procedimiento activo
Reservado Estructuras del
sistema operativo
Stack
Heap
Segmentode Texto
Reservado
0x0040 0000
0x0000 0000
0x1000 0000
0x7FFF FFFF
Algunas directivas al ensamblador
.dataTexto que sigue representa datos almacenados en el heap
.textTexto que sigue representa instrucciones almacenadas en áreade texto (código)
.kdataTexto que sigue representa datos en área de datos del kernel(sistema operativo)
.ktextTexto que sigue representa código en área de kernel
.globl LABELRótulo LABEL es global (visible a todo el programa)
.ascii strAlmacenar string de texto str en ASCII sin un NULL al final
.asciiz strAlmacenar string de texto str en ASCII con un NULL (0) al final
.word w1 … wnAlmacenar n palabras (32b) en posiciones consecutivas de memoria
.half h1 … hnAlmacenar n medias palabras (16b) en posiciones consecutivas de memoria
.byte b1 … bnAlmacenar n bytes (8b) en posiciones consecutivas de memoria
Ejemplo
.dataTEXTOSINULL: .ascii “texto 1”TEXTOCONUL: .asciiz “texto 2”DATOS: .word 16 124 1000
.text
.globl MAINMAIN: la $8, TEXTOSINUL
la $9, TEXTOCONULla $10, DATOSlw $11, 0($10)lw $12, 4($10)lw $13, 8($10)
Procedimientos
Son un componente importante en la estructura y modularidad de programas
Llamado y retorno requiere un protocolo del que llama y el que es llamado
Protocolo está basado en convención
Protocolo Procedimientos/funciones Cada máquina y compilador tiene su propio protocolo Protocolo esta determinado por HW y SW
Instrucción “jal” es HW Usar registro $29 como $sp es SW (convención)
Protocolo está determinado por una secuencia de pasos que se siguen por cada llamado y retorno
En RISC HW realiza instrucciones sencillas SW controla (compilador/ensamblador) controla secuencia de
instrucciones Registros utilizados
$ra $a0-$a3 $v0-$v2 $29 para puntero a stack
Instrucciones jal, jr
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 = strjal STRLEN; # resultado retorna en $v0
STRLEN: li $v0, 0 # len = 0
WHILE: lb $t0, 0($a0) # $t0 = *strbeq $t0, $zero, FIN_WHILE # if (*str == 0) goto FIN_W
addi $a0, $a0, 1 # str = str + 1addi $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
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 = 100jal PUNTO # resultado en $v0la $t0, RESsw $v0, 0($t0)…
PUNTO: li $t0, 0 # i = 0li $v0, 0 # suma = 0
WHILE: sll $t1, $t0, 2 # $t1 = i*4add $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 + 1slt $t3, $t0, $a2 # i < n?bne $t3, $zero, WHILEjr $ra
Qué hacer cuando los registros no son suficientes?
Algunas preguntas Registros para paso de argumentos: $a0-$a3
¿Qué hacer cuando hay más de 4 argumentos? Retorno de valor: $v0-$v1
¿Qué hacer cuando el valor de retorno utiliza más de dos palabras (ej. una estructura)?
Registros preservados por procedimiento invocado: $s0-$s7 ¿Dónde debe respaldarlos el procedimiento?
Registros preservados por procedimiento que invoca: $t0-$t9 ¿Dónde respaldarlos?
Dirección de retorno almacenada en: $ra ¿Qué hacer con su contenido si procedimiento invoca a otro
procedimiento? En general, ¿qué hacer cuando se nos acaban los
registros que estamos utilizando?
Datos locales y procedimientos recursivos Respuesta: el único lugar donde pueden almacenarse estos
datos es la memoria Alternativa 1: almacenarlos en área de memoria global asociada
al procedimiento
PROC1: move $t0, $a0…la $s0, PROC1_MEMsw $t0, 0($s0)sw $ra, 4($s0)jal PROC2lw $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?
Direccionesde memoria
Procedimientos y stacks Alternativa 2: definir un área de memoria asociada a cada activación de cada
procedimiento Estructura dinámica de llamado a procedimientos asemeja una pila (stack)
Retornan en el sentido inverso en el que fueron invocados Memoria para almacenamiento de datos locales también se estructura como
un stack
A
A
A
A
A
B
B
B
C
A:call B
B:call C
C:ret
ret
…
…
Stacks de memoria
Almacenan ambientes asociados a procedimientos anidados (marco de activación) Dirección de retorno Argumentos Variables locales Valor de retorno Registros salvados por el procedimiento
Soporte para stacks
Stack pointer (SP) Apunta al tope del stack Usado para agregar y sacar datos a stack
Frame pointer (FP) Apunta a base del bloque de activación (stack
frame) Usado para accesar variables locales y
argumentos sin removerlos del stack Operaciones
PUSH POP CALL RETURN
Soporte ISA para stacks En el lenguaje de máquina: VAX, Intel,
registros e instrucciones específicas Por convención de software: MIPS
Soporte mínimo: jal, jr
Argumentos
Registros salvados por el llamado
Variableslocales
Evaluación deexpresiones(dinámico)
FP
SP
Ejemplo: Cadena de llamados
Estructura de código
p1(…){
••p2();••
}
p2(…){
• • •p3();• • •p3();• • •
}
p3(…){
••p3();••
}
p1
p2
p3
p3
p3
Cadena de llamados
Procedimiento p3 es recursivo
p3
StackPointer
$sp
p1
•••
FramePointer
$fp
p1
Cadena de llamadosp1(…){
••p2();••
}
Operación del stack
Operación del stack
StackPointer
$sp
p1
p2
•••
FramePointer
$fpp1
p2
Cadena de llamadosp2(…){
• • •p3();• • •p3();• • •
}
Operación del stack
StackPointer
$sp
p1
p2
p3
•••
FramePointer
$fp
p1
p2
p3
Cadena de llamadosp3(…){
••p3();••
}
Operación del stack
StackPointer
$sp
p1
p2
p3
•••
FramePointer
$fp
p1
p2
p3
Cadena de llamadosp3(…){
••p3();••
}
p3p3
Operación del stack
StackPointer
$sp
p1
p2
p3
•••
FramePointer
$fp
p1
p2
p3
Cadena de llamadosp3(…){
••p3();••
}
p3p3
p3
p3
Operación del stack
StackPointer
$sp
p1
p2
p3
•••
FramePointer
$fp
p1
p2
p3
Cadena de llamadosp3(…){
••p3();••
}
p3p3
amI
Operación del stack
StackPointer
$sp
p1
p2
p3
•••
FramePointer
$fp
p1
p2
p3
Cadena de llamadosp3(…){
••p3();••
}
p3
p3
Operación del stack
StackPointer
$sp
p1
p2
•••
FramePointer
$fpp1
p2
Call Chainp2(…){
• • •p3();• • •p3();• • •
} p3
p3
p3
Operación del stack
StackPointer
$sp
p1
p2
p3
•••
FramePointer
$fp
p1
p2
Cadena de llamadosp3(…){
••••
}p3
p3
p3
p3
Operación del stack
StackPointer
$sp
p1
p2
•••
FramePointer
$fpp1
p2
Cadena de llamadosp2(…){
• • •p2();• • •p2();• • •
} p3
p3
p3
p3
Operación del stack
p1(…){
••p2();••
}
StackPointer
$sp
p1
•••
FramePointer
$fp
p1
p2
Cadena de llamados
p3
p3
p3
p3
Stack (Pila) de Programa
Cada programa en ejecución (proceso) tiene un stack Stack: estructura de datos dinámica accesada en LIFO Stack de programa automáticamente asignada por el SO 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 Después de eso queda a manos del programador el uso del
stack Por convención, el stack crece hacia direcciones más bajas
Para asignar una nueva entrada (al hacer push), decrementar $sp
Para liberar espacio en el tope del stack (al hacer pop), incrementar $sp
Operación push
Push agrega un item en el tope del stack Una instrucción para manipular dato : “sw $6, 0($sp)” Una instrucción para ajustar el puntero al stack : “subu $sp, $sp, 4”
antes después
46
-72
???
46
-72
127
???
8($sp)
4($sp)
$sp
12($sp)
8($sp)
4($sp)
$sp
127 $6 127 $6
Operación pop
Pop remueve un item del tope del stack y lo almacena en un registro Una instrucción para ajustar el puntero a stack : “addu $sp, $sp,
4” Una instrucción para manipular el dato : “lw $6, 0($sp)”
antes
46
-72
127
46
-72
127
???
8($sp)
4($sp)
$sp
12($sp)
8($sp)
4($sp)
$sp
127 $6 453 $6Pasa a ser
basura
despúes
Requerimientos llamados a procedimiento
El que llama debe pasar la dirección de retorno al que es llamado (procedimiento)
El que llama debe pasar los parámetros al procedimiento
El que llama debe guardar el contenido de los registros que podrían ser usados por el procedimiento
El procedimiento debe guardar la dirección de retorno (si es que llama a otro procedimiento o el mismo si es recursivo)
El procedimiento debe proporcionar almacenamiento de stack para su propio uso
Mecanismo
Registros son usados Para pasar dirección
de retorno en $ra Jal target
Para pasar parámetros ($a0 … $a3, a lo más 4)
Mantener el valor de $sp
Retornando valores de función en $v0, $v1
Stacks son usados para Salvar registros para
ser usados por procedimientos
Salvar información acerca del que llama (dirección de retorno)
Pasar parámetros si se necesita
Asignando datos locales para el procedimiento llamado
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
UsoNombre Registro
Tareas del que llama y procedimiento llamado en CALL
El que llama Salva contenido de
registros volatiles ($t0…$t9) teniendo contenidos que deben ser guardados
Poner a lo más 4 argumentos en $a0…$a3
Si hay más de 4 argumentos, poner el resto en el stack
Llamar a jal instrucción
Procedimiento Salva $ra en stack Salva cualquier registro
no volátil ($s0…$s7) que se usará
Tareas del que llama y procedimiento llamado en RETURN
Procedimiento Restaura cualquier
registro no volátil ($s0…$s7) que ha usado
Restaura $ra Pone resultados de
función en $v0, $v1 Retorna al que
llama con instrucción “jr $ra”
El que llama Restaura cualquier
registro volátil que ha salvado
Examina $v0 y $v1 si lo necesita
Ejemplo de un CALL
Asumir que los argumentos en $t0 y $t3 y que se desea salvar los contenidos en $t6 y $t7
move $a0,$t0 # argumento 1 en $a0
move $a1,$t3 # argumento 2 en $a1subu $sp,$sp,8 #espacio para 2 temps en stacksw $t6,8($sp) #salvar $t6 en stack
sw $t7,4($sp) #salvar $t7 en stack jal target
Asumir que procedimiento no necesita salvar registrostarget: sw $ra,0($sp) #salva dirección de retorno subu $sp,$sp,4 # en stack
Ejemplo RETURN
El procedimiento pondrá valores de retorno en $v0, $v1addu $sp,$sp,4 #poplw $ra,0($sp) #dir de retorno en $rajr $ra #para el que llama
El que llama restaura $t6 y $t7 y ajusta stacklw $t6,8($sp)lw $t7,4($sp)addu $sp,$sp,8
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 ConTEXTEjercicio: hacer dibujo con marcos de activación y cadena de llamados
Excepciones
Condiciones especiales que cambian el flujo de ejecución normal del programa
Tipos de excepciones Interrupción
Generada en forma externa al procesador, típicamente por dispositivo de E/S como interfaz de red o disco
Trap Efecto colateral (implícito o explícito) de ejecución
de instrucción Ej. División por cero, acceso ilegal a memoria,
instrucción inválida, syscall, break.
Atención de excepciones
Típicamente Almacenar estado del procesador (PC,
registro de condición, máscara de interrupciones, etc.)
Transferir control al sistema operativo Pasar a modo de ejecución supervisor Sistema operativo atiende excepción,
restaura el estado y retorna al programa de usuario
Atención de excepciones en MIPS
Registros que controlan estado de procesador Parte del coprocesador 0 Accesados mediante instrucciones mfc0 y mtc0
Registro Causa
Registro de estado
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
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).