¡Descarga Transparencias PCSPIM 3 y más Apuntes en PDF de Ingeniería Telemática solo en Docsity!
• OPERACIONES CON EL MIPS R
Para realizar cualquier operación con el hardware del MIPS R2000, hay que seguir una
determinada estructura donde se especifican todos los elementos que se utilizan en la
ejecución de dicha instrucción.
Una instrucción general puede estar compuesta (como máximo) de los siguientes elementos:
Instrucción Rdest, Rscr1, Scr
Donde:
• Instrucción , indica el tipo de operación que se quiere realizar.
• Rdest: Registro destino, es el registro donde se va a almacenar el valor resultante de
la operación.
• Rsrc1, Rscr2: Registros fuentes, son los registros desde donde se obtienen los
operandos de la instrucción que se pretende realizar.
Ejemplo: add $8, $9, $10 realiza la siguiente operación ($8) = ($9) +
$8, $9, $10 Son los registros donde se almacenan los valores que se utilizan en la
operación.
Hay otras instrucciones que necesitarán otro número de operandos:
• Dos registros: mult Rsrc1, Rsrc
• Un registro: mtlo Rdest
• Ningún registro: j label
- OPERANDOS
- Los operandos de la instrucciones deben estar localizados en celdas de almacenamiento en el
interior del procesador, denominados REGISTROS.
- Cada registro almacena datos de 32 bits (word).
- El procesador MIPS R2000 tiene 32 registros, y la notación empleada para referirnos a ellos es:
- (^) Los criterios de uso de los registros son:
Número
de
registro
Nombre Utilización
0 $zero Constante 0
1 $at Reservado para el ensamblador
2-3 $v0-v1 Ubicación del resultado de una
función
4-7 $a0-$a3 Paso de argumentos a subrutinas
$t0-$t7,
$t8, $t
Variables temporales
16-23 $s0-$s7 Variables permanentes
26-27 $k0-$k1 Registros reservados para uso del
núcleo del S.O.
28 $gp Puntero al área global de datos
29 $sp Puntero de pila
30 $fp Puntero de marco
31 $ra Dirección de retorno
- modos de direccionamiento
REPERTORIO DE INSTRUCCIONES DEL MIPS.
• Dentro de las instrucciones y pseudoinstrucciones podemos diferenciar 9 subapartados. (de casi 150
instrucciones veremos 120 aprox.)
• Instrucciones aritmético/lógicas.
• Instrucciones de manipulación de constantes.
• Instrucciones de comparación.
• Instrucciones de salto y bifurcación.
• Instrucciones de carga.
• Instrucciones de almacenamiento.
• Instrucciones de desplazamiento de datos.
• Instrucciones de punto flotante.
• Instrucción para llamar al sistema operativo.
Convenios en el uso de las instrucciones.
• En todas las instrucciones que se describen seguidamente, “Scr2” puede ser un registro o un entero (valor
inmediato).
• Las instrucciones generales (ejemplo add), en las que uno de los operandos es una constante. El
ensamblador las traducirá a instrucciones inmediatas (por ejemplo addi). De esta manera se evita el acceso
a memoria.
Instrucciones aritmético/lógicas (A) Se utilizan para realizar operaciones aritméticas y lógicas en
ensamblador MIPS
- abs Rdest, Rsrc #Valor Absoluto*
- add Rdest, Rsrc1, Src2 #Suma (con desbordamiento)
- addu Rdest, Rsrc1, Src2 #Suma (sin desbordamiento)
- addi Rdest, Rsrc1, Inm #Suma Inmediato (con desbordamiento)
- addiu Rdest, Rsrc1, Inm #Suma Inmediato (sin desbordamiento)
- and Rdest, Rsrc1, Src2 #AND
- andi Rdest, Rsrc1, Inm #AND Inmediato
- div Rsrc1, Rsrc2 #División (con signo)
- divu Rsrc1, Rsrc2 #División (sin signo)
- div Rdest, Rsrc1, Src2 #División (con signo)*
- divu Rdest, Rsrc1, Src2 #División (sin signo) *
- mult Rsrc1, Rsrc2 #Multiplicación
- multu Rsrc1, Rsrc2 #Multiplicación (sin signo)
- mul Rdest, Rsrc1, Src2 #Multiplicación (sin desbordamiento) *
- mulo Rdest, Rsrc1, Src2 #Multiplicación (con desbordamiento) *
- mulou Rdest, Rsrc1, Src2 #Multiplicación sin signo (con desbordamiento) *
- neg Rdest, Rsrc #Cambio signo (con desbordamiento) *
- negu Rdest, Rsrc #Cambio signo (sin desbordamiento) *
Instrucciones aritmético/lógicas
(B)
Se utilizan para realizar operaciones aritméticas y lógicas en
ensamblador MIPS
- nor Rdest, Rsrc1, Src2 #NOR
- not Rdest, Rsource #NOT*
- or Rdest, Rsrc1, Src2 #OR
- ori Rdest, Rsrc1, Inm #OR Inmediato
- rem Rdest, Rsrc1, Src2 #Resto*
- remu Rdest, Rsrc1, Src2 #Resto Sin signo*
- rol Rdest, Rsrc1, Src2 #Rota a la izquierda*
- ror Rdest, Rsrc1, Src2 #Rota a la derecha*
.text .globl __start __start: li $t1,0x1234fedc li $t0,0x01ab mult $t0,$t
Instrucciones de manipulación de
constantes
Permiten trabajar con números enteros (constantes)
- li Rdest, Inm #Carga Inmediata*
- lui Rdest, Inm #Carga Inmediata en parte alta. Ejemplo. li $v0,1 # Carga en el registro $v0, la constante 1.
(Se traducirá a una instrucción ori)
li $v0,1000000 # Carga en el registro $v0, la constante 1000000.
(Se traducirá en un par de instrucciones lui y ori)
lui $8,255 # Carga la constante 255 en el registro $8. 0000 0000 1111 1111 0000 0000 0000 0000
Instrucciones de
comparación
Permiten comparar los valores guardados en los registros (mayor, mayor
o igual, menor etc.)
- seq Rdest, Rsrc1, Src2 #Establece si es igual*
- sge Rdest, Rsrc1, Src2 #Establece si mayor o igual que*
- sgeu Rdest, Rsrc1, Src2 #Establece si mayor o igual que sin signo*
- sgt Rdest, Rsrc1, Src2 #Establece si mayor que*
- sgtu Rdest, Rsrc1, Src2 #Establece si mayor que sin signo*
- sle Rdest, Rsrc1, Src2 #Establece si menor o igual que*
- sleu Rdest, Rsrc1, Src2 #Establece si menor o igual que sin signo*
- slt Rdest, Rsrc1, Src2 #Establece si menor que
- slti Rdest, Rsrc1, Inm #Establece si menor que Inm
- sltu Rdest, Rsrc1, Src2 #Establece si menor que sin signo
- sltiu Rdest, Rsrc1, Inm #Establece si menor que Inm sin signo
- sne Rdest, Rsrc1, Src2 #Establece si no igual que*
Ejemplo.
li $t1, slt $t0,$t1, li $t1, slt $t2,$t1,
Instrucciones de salto y bifurcación
(A)
Permiten realizar saltos condicionales e incondicionales a otras
direcciones de programa
- b label #Instrucción de salto incondicional*
- bczt label #Salto coprocesador z cierto
- bczf label #Salto coprocesador z falso
- beq Rsrc1, Src2, label #Salta si igual
- beqz Rsrc, label #Salta si igual que cero*
- bge Rsrc1, Src2, label #Salta si mayor o igual que*
- bgeu Rsrc1, Src2, label #Salta si mayor o igual que sin signo*
- bgez Rsrc, label #Salta si mayor o igual que cero
- bgezal Rsource, label #Salta si mayor o igual que cero y enlaza
- bgezal Rsource, label #Salta si mayor o igual que cero y enlaza
- bgt Rsrc1, Src2, label #Salta si mayor que*
- bgtu Rsrc1, Src2, label #Salta si mayor que sin signo*
- bgtz Rsrc, label #Salta si mayor que cero
- ble Rsrc1, Src2, label #Salta si menor o igual que*
- bleu Rsrc1, Src2, label #Salta si menor o igual que sin signo*
- blez Rsrc, label #Salta si menor o igual que cero
Instrucciones de carga Permiten almacenar en registros los datos almacenados en las direcciones de
memoria especificadas.
- la Rdest, address #Carga dirección*
- lb Rdest, address #Carga byte
- lbu Rdest, address #Carga byte sin signo
- ld Rdest, address #Carga doble palabra*
- lh Rdest, address #Carga media palabra
- lhu Rdest, address #Carga media palabra sin signo
- lw Rdest, address #Carga palabra
- lwcz Rdest, address #Carga palabra coprocesador z
MODOS DE DIRECCIONAMIENTO A MEMORIA.
Formato Cálculo de dirección Ejemplo (Registro) Contenido de registros lw $8,($4) Inmediato Inmediato lw $8,0x1001001c Inmediato (registro)* Inmediato + contenido de registro lw $8,1000($4) etiqueta Dirección de etiqueta lw $8,etiqueta etiqueta + inmediato Dirección de la etiqueta + inmediato lw $8,etiqueta + etiqueta + inmediato (registro) Dirección de la etiqueta + inmediato + Contenido de registro
lw $8,etiqueta +1000($4)
Instrucciones de almacenamiento Permiten guardar en memoria valores contenidos en registros.
- sb Rsrc, address #Almacena Byte
- sd Rsrc, address #Almacena doble palabra*
- sh Rsrc, address #Almacena media palabra
- sw Rsource, address #Almacena palabra
- lwcz Rdest, address #Carga palabra coprocesador z
Ejemplo.
.data #SEGMENTO DE DATOS. Var_a: .word 0x var_b: .byte 0xff .text #SEGMENTO DE CODIGO. .globl __start __start: lw $t0,var_a lb $t1,var_b la $t3,var_a sb $t1,($t3) .end
Instrucciones de desplazamiento de
datos.
Permiten mover valores entre registros.
- move Rdest, Rsrc #Transfiere*
- mfhi Rdest #Transfiere desde HI
- mflo Rdest #Transfiere desde LO
- c.lt.d CPsrc1,CPsrc2 #Compara menor que doble
- c.lt.s CPsrc1,CPsrc2 #Compara menor que simple
- cvt.d.s CPdest,CPsrc #Convierte simple a doble
- cvt.d.w CPdest,CPsrc #Convierte entero a doble
- cvt.s.d CPdest,CPsrc #Convierte doble a simple
- cvt.s.w CPdest,CPsrc #Convierte entero a simple
- cvt.w.d CPdest,CPsrc #Convierte doble a entero
- cvt.w.s CPdest,CPsrc #Convierte simple a entero
- div.d CPdest,CPsrc1,CPsrc2 #Divide punto flotante doble
- div.s CPdest,CPsrc1,CPsrc2 #Divide punto flotante simple
Instrucciones de punto flotante.
(B)
Permiten operar sobre números en punto flotante en simple precisión
(32 bits) y doble precisión (64bits).
- l.d CPdest,address #Carga punto flotante doble
- l.s CPdest,address #Carga punto flotante simple
- mov.d CPdest,CPsrc #Transfiere punto flotante doble
- mov.s CPdest,CPsrc #Transfiere punto flotante simple
- mul.d CPdest,CPsrc1,CPsrc2 #Multiplica punto flotante doble
- mul.s CPdest,CPsrc1,CPsrc2 #Multiplica punto flotante simple
- neg.d CPdest,CPsrc #Cambio signo doble
- neg.s CPdest,CPsrc #Cambio signo simple
- s.d CPdest,address #Almacena punto flotante doble
- s.s CPdest,CPsrc #Almacena punto flotante simple
- sub.d CPdest,CPsrc1,CPsrc2 #Resta punto flotante doble
- sub.s CPdest,CPsrc1,CPsrc2 #Resta punto flotante simple
Ejemplo.
.data #SEGMENTO DE DATOS. var_a: .double -35.2e- var_b: .double 20.2e- .text #SEGMENTO DE CODIGO. .globl __start __start: l.d $f0,var_a l.d $f2,var_b mul.d $f12,$f0,$f li $v0, syscall
Instrucciones de llamada al sistema operativo. Realiza una llamada al sistema operativo
- syscall #Llamada al sistema.
Código de llamada: $v0. ($2)
Enteros y cadena de caracteres Flotantes.
Entrada de parametros: $a0 ($4) , $a
Entrada de parametros: $f12.
Salida de parametros: $v0. Salida de parametros: $f
Servicio Código de llamada^ Argumentos^ Resultado
Escribir_entero (^1) $4 = entero Escribir_float (^2) $f12 = simple Escribir_double (^3) $f12 = doble Escribir_cadena (^4) $4 = cadena Leer_entero (^5) Entero en $ Leer_float (^6) Simple en $f Leer_double (^7) Doble en $f
PCSpim proporciona un conjunto de servicios similares a los que ofrecen los sistemas operativos reales a
través de una instrucción de llamada al sistema (syscall). El recurso más impórtate que va administra este
particular sistema operativo es la consola.
Para usar este servicio, el programa debe cargar el código de llamada del sistema en el registro $v0, y los
argumentos (en caso de que se necesiten) en los registros $a0, Y $a1 (o $f12 para flotantes). Las llamadas al
sistema que devuelven valores ponen su resultado en los registros $v0 (o $f0 para flotantes). (no es ni más ni
menos que un subprograma con paso de argumentos en ambas direcciones).
print_int, print_float, print_double y print_string.
respectivamente, imprimen en la consola un entero, un float (valor real en IEEE 754 simple precisión), un
double (valor real en IEEE 754 doble precisión), y una cadena ASCII que acabe con el byte 0x00,
respectivamente.
read_int,read_float, read_double y read_string son sus análogos para la lectura por teclado. El uso de los tres
primeros es trivial. Para usar read_string, sin embargo. Debe colocarse en $a1 el tamaño máximo (en bytes)
que puede tener la cadena leída, pero incluyendo un carácter nulo (0x00) al final de la misma. Así, si ponemos
en $a1 un valor n. PCSpim leerá del teclado como máximo n-1 caracteres, y colocará al final un byte nulo. Si
el usuario teclea los n-1 caracteres, PCSpim terminará automáticamente la entrada (sin necesidad de pulsar
intro). Si, por el contrario, el usuario teclea intro antes de llegar al último carácter, PCSpim coloca un carácter
0x0a en la última posición y a continuación el byte nulo 0x00,
SUMA DE SECUENCIA DE N ENTEROS LEIDOS POR CONSOLA.
########## SUMA UNA SECUENCIA DE N ENTEROS LEIDOS DE LA CONSOLA ########## ########## SEGMENTO DE DATOS ########## .data prompt1:.asciiz "Numero de enteros: " prompt2:.asciiz "Siguiente entero: " suma: .asciiz "La suma es: " retcarro:.asciiz "\n" ########## SEGMENTO DE CODIGO ########## .text main: ### RUTINA PRINCIPAL ### la $a0,prompt1 # Cargar en el registro de parámetro de llamada al sistema
la dirección de la cadena a imprimir
li $v0,4 # Número de servicio de llamada al sistema (print_string) syscall # Llamada al sistema que imprime una cadena li $v0, syscall # Llamada al sistema que lee un entero move $t0,$v0 # Guardamos n en $t li $t1,0 # Guardamos la suma en $t while: blez $t0,finwhile # Lectura de los n enteros li $v0, la $a0,prompt syscall # Llamada al sistema que imprime una cadena li $v0, syscall # Llamada al sistema que lee un entero add $t1,$t1,$v0 # Incrementar suma sub $t0, $t0, 1 # Decrementar n b while finwhile: li $v0, 4 la $a0, suma syscall # Llamada al sistema que imprime una cadena move $a0,$t li $v0, syscall # Llamada al sistema que imprime un entero li $v0, la $a0,retcarro syscall # Llamada al sistema que imprime una cadena li $v0, syscall # Fin del programa