Vous êtes sur la page 1sur 36

1.

Procesador MIPS
Consideraciones:
Tamao de palabra: 32 bits (4 bytes).
Tamao de media palabra: 16 bits (2 bytes).

Registros:
$t0
$t1

$zero: Registro especial cuyo valor es siempre 0.
$at: Registro especial para operaciones inmediatas.

Instrucciones:
Operaciones matemticas:
Sumar registros: add destino, origen1, origen2
add $t0, $t1, $t2 #Suma $t1 y $t2 y lo guarda en $t0
Suma inmediata con signo: addi destino, origen, aadido
addi $t0, $zero, 1 #Aade 1 al valor de $t0
Suma inmediata sin signo: addiu destino, origen, aadido
addiu $t0, $zero, 1 #Aade 1 al valor de $t0
Restar registros: sub destino, origen1, origen2
sub $t1,$1,$3 #Guarda en $t1 ($1 - $3)

Comparaciones:
Slt: slt destino,origen1,origen2
slt $at, $t4, $s2 #Si t4 < s2, at = 1,en caso contratio, at = 0
Igual: beq a, b, salto
Desigual: bne a, b, salto
bne $at, $zero, loop #Salta a loop si at != 0
Menor: blt a, b, salto (*)
slt $at, a, b
bne $at, $zero, salto
Mayor: bgt a, b, salto (*)
slt $at, b, a
bne $at, $zero, salto
Menor o igual: ble a, b, salto (*)
slt $at, b, a
beq $at, $zero, salto
Mayor o igual: bge a, b, salto (*)
slt $at, a, b
beq $at, $zero, salto
Menor o igual que 0: blez a, salto
blez $t1, loop #Salta si el contenido del registro es menor o igual
que 0

Operaciones lgicas, bit a bit:


Or: or $t0, $t1, $t2
And: and $t0, $t1, $t2
Xor: xor $t0, $t1, $t2
Nor: nor $t0, $t1, $t2

Desplazamientos:
Desplazamiento lgico a la izq: sll destino,origen,n de 0
sll $t3, $s1, 3 #Coge los bits desde el 28 hasta el 0 de s1 y les
aade 3 ceros por la derecha
Desplazamiento lgico a la der: srl destino, origen, n de 0
srl $t3, $s1, 3 #Coge los bits desde el 31 hasta el 3 de s1 y les
aade 3 ceros por la izquierda
Instrucciones de carga de datos:
Carga de una palabra (Load Word): lw destino, desplazamiento(origen)
lw $t1, 40($t3)
Carga media palabra (Half Word): lh destino, desplazamiento(origen)
lh $t1, 40($t3)
Carga media palabra SIN signo: lhu destino, desplazamiento(origen)
lhu $t1, 40($t3)
Carga de un byte: lb destino, desplazamiento(origen)
lb $t1, 40($t3)
Carga de un byte SIN signo: lbu destino, desplazamiento(origen)
lbu $t1, 40($t3)
Carga inmediata parte superior: lui destino, semipalabra?
lui $s2, 0x0987
Carga inmediato de 16 bits con signo: l i,destino, n (*)
li $t1,5000 #al n en hexadecimal le aade 16 0 por la izq y lo
guarda en t1
li $t1, -5000 #al n en hexadecimal le aade 16 1 por la izq y lo
guarda en t1
Carga inmediato de 32 bits: li,destino,n ( *)
li $t1, 0xa0b0c0 #carga el n entero en $t1

Carga inmediato de 16 bits sin signo: li,destino,n en hexadecimal ( *)


li $t1, 0xa0b0 #al n le aade 16 0 por la izq y lo guarda en t1

Instrucciones de almacenamiento de datos:


Almacenamiento de palabra: sw origen, desplazamiento(destino)
sw $t4, 56($s6)
Almacenamiento de media palabra: sh origen, desplazamiento(destino)
sh $t4, 56($s6)
Almacenamiento de byte: sb origen, desplazamiento(destino)
sb $t4, 56($s6)

Copia con registros hi / lo:


mfhi $t1: Copia desde hi
mflo $t1: Copia desde lo
mthi $t1: Copia hacia hi
mtlo $t1: Copia hacia lo
2. Procesador IA 32
Consideraciones:
Arquitectura CISC.
Tamao de palabra: 32 bits (4 bytes).

Registros de propsito general(32 bits):


EAX: Resultados operaciones.
EBX: Puntero a datos.
ECX: Contador.
EDX: Puntero a direcciones E/S.
ESI: Puntero a operando fuente (Instrucciones de cadenas).
EDI: Puntero a operando destino (Instrucciones de cadenas).
ESP: Puntero a la cima de la pila (Apunta al ltimo valor apilado).
EBP: Puntero de datos en la pila.
EIP: Registro de puntero a instruccin: Puntero a la siguiente instruccin a
ejecutar.
Podemos acceder tanto a los 32bits como a los 16 bits menos
significativos(mediante los identificadores AX,BX,CX,DX,SI,DI,SP,BP,IP).
En el caso de los 4 primeros podemos acceder al byte mas
significativo(identificadores AH,BH,CH,DH)y al menos
significativo(identificadores AL,BL,CL,DL).*aadir dibujo

Banderas(registro EFLAGS):
OF (bit 11): Se pone a 1 si hay overflow en operaciones con signo y
complemento a 2..
SF (bit 7): Signo del resultado de la ltima operacin con signo (1: Negativo).
ZF (bit 6): Se pondr a 1 si la ltima operacin aritmtica es cero.
CF (bit 0): Toma el valor 1 si hay acarreo. Contiene el valor del bit que sale en
los desplazamientos(En operaciones sin signo).
Para usarlo, ponemos jnX si queremos comprobar si es 0 o jX para ver si es 1

Registro de puntero a direccin(EIP):


Contiene la direccin de la ltima instruccin que se va a ejecutar.
Tipos de datos:
DB: Byte (8 bits).
DW: Palabra (16 bits).
DD: Doble palabra (32 bits).
DQ: Cuatruple palabra (64 bits).
NOTA IMPORTANTE: El procesador trabaja con palabras de 32 bits, sin
embargo, llama palabra a 16 bits.
El almacenamiento en memoria es little endian (el byte menos significativo del
dato se encuentra en la direccin ms baja de memoria).
Instrucciones:
Instrucciones de transferencia:
Copiar registro: MOV destino, origen
Apilar: PUSH registro
Desapilar: POP registro

Instrucciones aritmticas:
Suma sin acarreo: ADD destino/origen, origen
Suma con acarreo: ADC destino/origen, origen

Resta sin acarreo: SUB destino/origen, origen


Resta con acarreo: SBB destino/origen, origen

Multiplicacin sin signo: MUL destino/origen, origen


Multiplicacin con signo: IMUL destino/origen, origen

Divisin sin signo: DIV destino/origen, origen


Divisin con signo: IDIV destino/origen, origen

Incremento: INC destino


Decremento: DEC destino

Paso a negativo (Complemento a dos): NEG destino

Comparar y actualizar bandera: CMP origen, origen

Instrucciones lgicas:
Operacin AND bit a bit: AND destino/origen, origen
Operacin OR bit a bit: OR destino/origen, origen
Operacin XOR bit a bit: XOR destino/origen, origen
Operacin NOT bit a bit: NOT destino/origen

Operacin AND con activacin de banderas: TEST origen, origen


(Se utiliza normalmente con las instrucciones de salto condicional).

NOTA: Todas las instrucciones del tipo XXX destino/origen, origen significan que intervienen
ambos registros en la operacin pero que se guarda en el primero de ellos.
Instrucciones de desplazamiento:
Desplazamiento ARITMTICO a la izquierda: SAL registro, bits
Desplazamiento ARITMTICO a la derecha: SAR registro, bits

Desplazamiento LGICO a la izquierda: SHL registro, bits


Desplazamiento LGICO a la derecha: SHR registro, bits

Si no se indica bits nmero de bits el desplazamiento ser de uno.

NOTA: La diferencia entre el aritmtico y el lgico es que el aritmtico respeta el


bit de signo (de Ca2). En otras palabras, el lgico desplaza sin ms y el
aritmtico mantiene el signo.

Instrucciones de control de flujo:


Salto incondicional: JMP etiqueta

Salto decremental: LOOP etiqueta


Decrementa el valor de ECX (Contador) en cada salto hasta que llega a 0
y sale del bucle.

Salto condicional: JXX etiqueta.


En XX se colocan las banderas, que serian la condicin.

Llamada a subrutina o funcin: CALL etiqueta


Va a la parte de cdigo de la etiqueta y vuelve cuando encuentra el
return.

Retorno de salto: RET ?

Otras instrucciones:
?: LEA ?
5. OpenMp
Paralelizar un bloque:
#pragma omp parallel private(lista) shared(lista) firstprivate(lista) lastprivate(lista)
shared(list): Variable compartida.
private(list): Variable privada.
firstprivate(list): Para que una variable privada se inicialice con el valor que
tena antes de entrar en el bloque.Si no se indica esto, el valor inicial de la
variable es indeterminado (no inicializada).
lastprivate(list): Para que una variable conserve su valor una vez finalizado el
bloque,si no se indica,su valor final es indeterminado.

Paralelizacin de bucles:
#pragma omp for (Esta declaracin estar dentro del bloque paralelo previamente
declarado mediante #pragma omp parallel)
9. Open MPI
char p[MPI_MAX_PROCESSOR_NAME];
int tam;
MPI_Get_processor_name(p, &tam);

Cmo se comporta Open MPI cuando A enva (send) un mensaje a B?:


1) A se bloquea hasta que B recibe el mensaje.
2) A se bloquea hasta que se enva el mensaje.

Cuando el proceso B ejecuta un recive siempre se bloquea hasta que le mensaje ya est en el
buffer.
Ejercicios prctica 1:
1. Dado el siguiente fragmento de cdigo en lenguaje C:
r = 0;
a = 1;
b = 2;
if (a <= b)
r = 1;

Cdigo en ensamblador:
main:
addiu $t0, $zero, 0 #$t0 = r
addiu $t1, $zero, 1 #$t1 = a
addiu $t2, $zero, 2 #$t2 = b

bgt $t1, $t2, salto #Pseudoinstruccin


add $t0, $zero, 1
salto:
syscall

2. Explique qu relacin existe entre los valores inicial y final de t1


sub $t1, $zero, $t1
addi $t2, $zero, -1
xor $t1, $t1, $t2
addi $t1, $t1, 1

Paso a paso:
1. sub $t1, $zero, $t1
Resta a $t1 cero menos $t1, es decir, pone $t1 a 0.
$t1 = 0x00000000
2. addi $t2, $zero, -1
Suma (con signo) a $t2 el valor de menos uno, por tanto el valor de $t2 ser -1
$t2 = 0xFFFFFFFF
3. xor $t1, $t1, $t2
Guarda el resultado de la operacin exclusive-or de $t1 y $t2 en $t1
$t1 = 0xFFFFFFFF
4. addi $t1, $t1, 1
Aade (con signo) uno al valor de $t1
$t1 = 0x00000000

3. Teniendo en cuenta que el simulador MARS utiliza el ordenamiento little-endian Cul


es el valor del registro t1 despus de ejecutar el siguiente cdigo? Y si se ejecuta la
instruccin lbu en vez de lb?

.data
datos: .space 32
.text
la $t2, datos
lui $t1,0x8899
sw $t1, 16($t2)
lb $t1, 19($t2)

Ordenamiento little-endian: Los bytes menos significativos se guardan al principio.


Si queremos guardar en un registro el valor 1 se guardara en memoria de esta forma:

0 x 01 00 00 00
1er 2do 3er 4to
byte byte byte byte

Tenemos que tener en cuenta que 0x00 es un byte y que por tando 0x00000000 son 4 bytes
que es el tamao de palabra (8*4 = 32 bits). Cada posicin de memoria almacena UN byte.

Paso a paso:
1. la $t2, datos
$t2 = 0x10010000
2. lui $t1,0x8899
Rellena con ceros por la derecha y lo guarda en $t1
$t1 = 0x88990000
3. sw $t1, 16($t2)
Guarda el contenido de $t1 en la direccin de memoria que contiene $t2 con 16
bits de desplazamiento.
Primero sumamos 16 (10 en hexadecimal) a la direccin de memoria que
contiene $t2, es decir, a 0x10010000 le sumamos 10 = 0x10010010.
(0x10010010) = 0x88990000
4. lb $t1, 19($t2)
Carga un byte en un registro, en este caso el que est en la posicin
0x10010000 ms 19 (que es 13 en hexadecimal), es decir, en la direccin 0x10010013
$t1 = 0xFFFFFF88

4. Escriba una secuencia de instrucciones que salte a la direccin ETIQ si t1 es mayor o


igual a 0x12345. Utilice primero instrucciones reales y despus repita el ejercicio con
pseudoinstrucciones.

Con pseudoinstrucciones:
addiu $t1, $zero, 0x12345 # t1 = valor cambiante, a sustituir
bge $t1, 0x12345, etiq #salta a continua si t1 >= 0x12345
syscall
etiq: addiu $t0, $zero, 1 #t0 valdr uno si ha saltado a etiq y 0 si no lo ha hecho
syscall

Sin pseudoinstrucciones:
#addiu $t1, $zero, 0x12345 #t1 = valor cambiante, a sustituir
lui $t1, 0x0001
ori $t1, $t1, 0x2345
#bge $t1, 0x12345, etiq #salta a continua si t1 >= 0x12345
lui $at, 0x001
ori $at, $at, 0x2345
slt $at, $t1, $at #
beq $at, $zero, etiq #
syscall
etiq: addiu $t0, $zero, 1 #t0 valdr uno si ha saltado a etiq y 0 si no lo ha hecho
syscall
5. Escriba una secuencia de instrucciones que convierta una cadena de caracteres en
mayscula a minscula. La cadena comienza en la direccin a la que apunta la etiqueta
cadena y el valor 0 indica fin de cadena. Los caracteres de la 'a' a la 'z', tanto en
minscula como en mayscula, tienen cdigos ASCII consecutivos (A es el 65 y a el
97). Para convertir un carcter en mayscula 'Q' a minscula hay quecalcular, por tanto,
'Q'-65+97.

Nota: Cada letra en memoria ser un byte (0x00).


Adems, como hay datos en el programa es necesario aadir la etiqueta .data al principio del
mismo y la etiqueta .text cuando acabemos de definir los datos.

.data
cadena: .ascii "ABCDEFG0"

.text
la $t0, cadena #Nos traemos la direccin de memoria en la que se almacena la cadena a $t0
bucle: lb $t1, 0($t0)
beq $t1, 48, fin #Si $t1 = 48, que es el valor ASCII de 0, entonces se sale del bucle
addiu $t1, $t1, 32 #Le sumamos 32 a la palabra para pasarla a minscula
sb $t1, 0($t0)
addiu $t0, $t0, 1
j bucle #Salta al bucle de nuevo
fin: syscall
6. Escriba un programa en ensamblador del MIPS equivalente a la siguiente porcin de
cdigo en lenguaje de alto nivel (lenguaje C):
i = 15;
if (i < 10)
r = 0;
else if (i < 20)
r = 1;
else
r = 2;

addiu $t0, $zero, 15


blt $t0, 10, menorDiez
blt $t0, 20, menorVeinte
addiu $t1, $zero, 2
syscall

menorDiez: addiu $t1, $zero, 0


syscall
menorVeinte: addiu $t1, $zero, 1
syscall

7. Las estructuras iterativas de los lenguajes de alto nivel se traducen usando una
instruccin de salto condicional (que puede ir precedida de una instruccin slt) para
implementar la condicin del bucle, adems de una instruccin de salto incondicional
para volver al comienzo del bucle y ejecutar la siguiente iteracin.
Como ejemplo, vamos a traducir la siguiente porcin de cdigo en C:
x = 4;
res = 0;
for ( i = 0; i < x; ++i)
res = res + 3;
Ejecute el programa en el simulador MARS y compruebe si tras la ejecucin el valor del
registro
equivalente a la variable res tiene el valor adecuado.

S, contiene el valor adecuado (12).

addiu $t0, $zero, 4 #x=4


addiu $t1, $zero, 0 #res=0
addiu $t2, $zero, 0 #i=0
bucle: bge $t2, $t0, fin
addiu $t2, $t2, 1 #incrementa el contador
addiu $t1, $t1, 3 #res=res+3
j bucle
fin: syscall
8. Escriba un programa en ensamblador del MIPS equivalente a la siguiente porcin de
cdigo en lenguaje de alto nivel (lenguaje C):
x = 4;
res = 0;
i = 1;
while (i <= x) {
res = res + 2;
++i;
}

addiu $t0, $zero, 4 #x=4


addiu $t1, $zero, 0 #res=0
addiu $t2, $zero, 1 #i=1
bucle: bgt $t2, $t0, fin
addiu $t1, $t1, 2 #res=res+2
addiu $t2, $t2, 1 #incrementa el contador
j bucle
fin: syscall

9. Consideremos el siguiente programa en lenguaje de alto nivel (lenguaje C), que suma
dos vectores o arrays guardando el resultado en un tercer vector y adems acumula la
suma de todos los elementos en una variable:
int n = 3, suma = 0;
int a[3] = {1, 3, 5};
int b[3] = {2, 4, 6};
int r[3];
main() {
int i;
for (i = 0; i < n; ++i) {
r[i] = a[i] + b[i];
suma += r[i];
}
}

.data
arrayA: .space 32
arrayB: .space 32
arrayR: .space 32
.text
#Inicializar variables
addiu $t0, $zero, 3 #n=3
addiu $t1, $zero, 0 #suma=0
addiu $t2, $zero, 0 #i=0
#Ahora vamos a utilizar $t3 como registro auxiliar
#Inicializar array A
la $t7, arrayA #Nos traemos la direccin de memoria reservada al array A
addiu $t3, $zero, 1 #Lo que vamos a guardar
sb $t3, 0($t7) #Lo guardamos en el espacio de memoria de array A
addiu $t7, $t7, 1 #Incrementamos la direccin de memoria de A en 1
addiu $t3, $zero, 3 #Lo que vamos a guardar
sb $t3, 0($t7) #Lo guardamos en el espacio de memoria de array A
addiu $t7, $t7, 1 #Incrementamos la direccin de memoria de A en 1
addiu $t3, $zero, 5 #Lo que vamos a guardar
sb $t3, 0($t7) #Lo guardamos en el espacio de memoria de array A

#Inicializar array B
la $t8, arrayB #Nos traemos la direccin de memoria reservada al array B
addiu $t3, $zero, 2 #Lo que vamos a guardar
sb $t3, 0($t8) #Lo guardamos en el espacio de memoria de array B
addiu $t8, $t8, 1 #Incrementamos la direccin de memoria de B en 1
addiu $t3, $zero, 4 #Lo que vamos a guardar
sb $t3, 0($t8) #Lo guardamos en el espacio de memoria de array B
addiu $t8, $t8, 1 #Incrementamos la direccin de memoria de B en 1
addiu $t3, $zero, 6 #Lo que vamos a guardar
sb $t3, 0($t8) #Lo guardamos en el espacio de memoria de array B

#Cuerpo del problema


la $t7, arrayA #Nos traemos la direccin de memoria reservada al array A
la $t8, arrayB #Nos traemos la direccin de memoria reservada al array B
la $t9, arrayR #Nos traemos la direccin de memoria reservada al array R

bucle: bge $t2, $t0, fin


lb $t3, ($t7) #Cargamos el valor correspondiente del array A
lb $t4, ($t8) #Cargamos el valor correspondiente del array B
add $t5, $t3, $t4 #Valor a guardar en el array R y a sumar en suma
sb $t5, ($t9) #r[i] = a[i] + b[i];
add $t1, $t1, $t5 #suma += r[i];
addiu $t7, $t7, 1 #Incrementamos la direccin de memoria de A en 1
addiu $t8, $t8, 1 #Incrementamos la direccin de memoria de B en 1
addiu $t9, $t9, 1 #Incrementamos la direccin de memoria de R en 1
addiu $t2, $t2, 1 #El contador lo aumentamos en 1
j bucle

fin: syscall
Cuestiones prctica 2:
1. Indique que contiene el registro EAX tras ejecutar cada uno de los siguientes trozos de
cdigo:
a. mov eax, 11AA22BBh ;eax = 0x11AA22BB
mov [1000h], eax ;eax = 0x11AA22BB
mov dword ptr [1004h], 22BB33CCh ;eax = 0x11AA22BB
mov eax, [1002h] ;eax = 0x33CC11AA

b. mov eax, 11AA22BBh ;eax = 0x11AA22BB


mov [1000h], eax ;eax = 0x11AA22BB
mov al, [1003h] ;eax = 0x11AA2211
mov ah, [1002h] ;eax = 0x11AAAA11

c. mov eax, 11AA22BBh ;eax = 0x11AA22BB


mov [1000h], eax ;eax = 0x11AA22BB
mov al, [1000h] ;eax = 0x11AA22BB
shl eax, 8 ;eax = 0xAA22BB00
mov al, [1001h] ;eax = 0xAA22BB22
shl eax, 8 ;eax = 0x22BB2200
mov al, [1002h] ;eax = 0x22BB22AA
shl eax, 8 ;eax = 0xBB22AA00
mov al, [1003h] ;eax = 0xBB22AA11

2. Tenemos dos valores enteros sin signo de 64 bits en los registros EBX:EAX y
EDX:ECX. Escriba un trozo de cdigo que calcule la suma de dichos valores y la
almacene en EBX:EAX.
add eax, ecx ;Suma la parte baja de ambos nmeros y guarda el resultado en EAX.
adc ebx, edx ;Suma la parte alta de ambos nmeros teniendo en cuenta el acarreo (al
realizarse la operacin anterior el bit de acarreo, CF, se habr activado si se produjo el mismo).
3. Dadas dos variables x e y de 32 bits que se encuentran en las direcciones de memoria
EBP-4 y EBP-8, respectivamente; escriba, para cada una de las siguientes condiciones,
un trozo de cdigo que salte a la etiqueta FIN si se cumple la condicin:
a) el bit 7 de x vale 0
.386
.model flat
option casemap:none
.data
.code
start:
mov ebx, 1
mov eax, 0FFh
test eax, 80h ;El valor hexadecimal 80 tiene todos los bits a 0 salvo el sptimo
jz fin
mov ebx, 0
;EBX indica si ha saltado (1) o si no lo ha hecho (0)
fin:
end start
end

(HAY QUE HACERLO CON LOS REGISTROS ADECUADOS)

b) el bit 31 de y vale 1
c) x > y (suponiendo que x e y son enteros con signo)

d) x > y (suponiendo que x e y son enteros sin signo)


Ejercicios prctica 2:
1. Estudie el cdigo del siguiente programa. Qu valor debe tener el vector vectres al
finalizar la ejecucin?
.386
.model flat
option casemap:none
.data
vect1 DD 1,2,3,4,5,6,7,8,9,10 ;DD indica que cada elemento se almacenar en 32 bits
vect2 DD 10,9,8,7,6,5,4,3,2,1
vectres DD 1,2,3,4,5,6,7,8,9,10
.code
start:
mov ecx, 10 ;ecx = 10
xor edx, edx ;Al hacer un xor consigo mismo siempre se obtiene cero, por tanto, edx = 0
inibucle:
mov eax, [edx + vect1] ;1it) eax = 1 / 2it) eax = 2
add eax, [edx + vect2] ;1it) eax = eax + 10 = 11 / 2it) eax = eax + 9
mov [edx + vectres], eax ;1it) vectres = 11,2,3,4,5,6,7,8,9,10 / 2it) vectres = 11, 11, 3, 4, 5, ...
add edx, 4 ;Aadimos 4 para avanzar a la siguiente posicin(cada elemento ocupa 4 bits)
loop inibucle
end start
end

El vector vectres al finalizar la ejecucin del programa contendr en todos sus elementos (10
en total) el valor 11 (0x0b en hexadecimal):
vectres = 0b, 0b, 0b, 0b, 0b, 0b, 0b, 0b, 0b, 0b

En otras palabras, el algoritmo lo que hace es sumar los valores de vect1 con sus pares de
vect2 y guardarlo en vectres. Por tanto, vectres se podr inicilizar con cualquier valor (ya que,
obviamente, no se accede nunca a sus datos, slo se nombra en el cdigo para guardar datos).
2. Escriba un programa en ensamblador que calcule el sumatorio de los elementos de un
vector.
Los elementos del vector son enteros sin signo de 32 bits y el sumatorio debe
almacenarse en un variable de 64 bits por si el resultado ocupa ms de 32 bits (para ello
debe tener en cuenta el bit de carry de las sumas parciales). Reutilice el cdigo del
ejercicio anterior con la siguiente definicin de datos:
.386
.model flat
option casemap:none
.data
vect1 DD 1,2,3,4,5,6,7,8,9,10
suma DQ ?

.386
.model flat
option casemap:none
.data
vect1 DD 1,2,3,4,5,6,7,8,9,10
suma DQ ?
.code
start:
mov eax, 0 ;Variable resultado
mov ecx, 10 ;Contador
mov edx, 0 ;Desplazamiento (de 4 en 4)
inibucle:
add eax, [edx + vect1] ;Almacenamos el valor
add edx, 4 ;Aadimos 4 para avanzar a la siguiente posicin que contenga elementos del array
loop inibucle
;mov suma, eax
end start
end
3. Escriba un programa en ensamblador que, dada una cadena de caracteres en
minscula obtenga, otra cadena similar pero con las letras en maysculas. Para ello
tenga en cuenta que:
Cada carcter ocupa un byte
El valor de la letra a es 97 y de la letra A es 65
Utilice la definicin de datos siguiente:
.386
.model flat
option casemap:none
.data
cadena db "holamundo",0
cadena2 db 20 dup (?)

3.1 Escriba una primera versin suponiendo que la cadena de entrada slo tiene letras
minsculas.
.386
.model flat
option casemap:none
.data
cadena db "holamundo",0
cadena2 db 20 dup (?)
.code
start:
mov edx, 0 ;Desplazamiento (de 1 en 1)
inibucle:
mov al, [edx + cadena]
cmp al, 0
jz fin
sub al, 32
mov [edx + cadena], al
add edx, 1 ;Aadimos 1 para avanzar a la siguiente posicin que contenga elementos del array
jmp inibucle
fin:
end start
end
3.2 Escriba una segunda versin ms completa teniendo en cuenta que la cadena de
entrada puede estar formada por cualquier carcter y que slo debe modificar los
caracteres que se correspondan con letras minsculas. Para probar la solucin utilice
una cadena diferente a la del ejemplo.

.386
.model flat
option casemap:none
.data
cadena db "HolaMundo",0
cadena2 db 20 dup (?)
.code
start:
mov edx, 0 ;Desplazamiento (de 1 en 1)
inibucle:
mov al, [edx + cadena]
;Comprobamos si el carcter es cero (y finalizamos en dicho caso)
cmp al, 0
jz fin
;Comprobamos si restndole 97 ("a") el resultado es negativo (-1 mnimo, en dicho caso es
mayscula)
mov bl, al
sub bl, 97
js esMayuscula
;Sigue aqu si el carcter es minsculas
esMinuscula: sub al, 32
mov [edx + cadena], al
add edx, 1 ;Aadimos 1 para avanzar a la siguiente posicin que contenga elementos del array
jmp inibucle
;Salta aqu el carcter es maysculas
esMayuscula: add al, 32
mov [edx + cadena], al
add edx, 1 ;Aadimos 1 para avanzar a la siguiente posicin que contenga elementos del array
jmp inibucle
fin:
end start
end
4. Escriba un programa que calcule el factorial de una variable n almacenada en
memoria. La variable es un entero sin signo de 32 bits. Reutilice el cdigo del ejercicio 2
con la siguiente definicin de datos:
.386
.model flat
option casemap:none
.data
n DD 4
fact DD ?

.386
.model flat
option casemap:none
.data
n DD 4
fact DD ?
.code
start:
mov eax, 1 ;Variable resultado
mov ecx, n ;El nmero de vueltas del bucle viene dado por el mismo "n"
mov edx, 0 ;Desplazamiento (de 4 en 4)
inibucle:
mul ecx
mov [fact], eax
loop inibucle
end start
end
Cuestiones prctica 3:
1. Traduzca a instrucciones del IA32 los siguientes fragmentos de cdigo MIPS:
a) Salta si $t3<= $t4:
sub $t1, $t3, $t4 #Resta $t3 menos $t4 y lo guarda en $t1
blez $t1, sigue #Si $t1 es menor o igual que 0 entonces salta a sigue

Salta si eax<= ebx:


sub eax, ebx #Resta EAX menos EBX
jsf, sigue #Si el bit SF est activado (Ser 1 si el resultado fue negativo) salta a sigue
jzf, sigue #Si el bit ZF est activado (Ser 1 si el resultado fue cero) salta a sigue
Otra opcin:
cmp eax,ebx#combapra ambos registros y actualiza las anderas
jbe sigue#comprueba las banderas y salta si op1<=opt2

b) Salta si $t3 >= $t4:


sub $t1, $t4, $t3 #Resta $t3 menos $t4 y lo guarda en $t1
blez $t1, sigue #Si $t1 es mayor o igual que 0 entonces salta a sigue

Salta si eax>= ebx:


sub ebx,eax
jzf,sigue
jsf,sigue
Otra opcin:
cmp eax,ebx
jae sigue

c) Resta 5 a un dato almacenado en la direccin $t3+$t4+100:


add $t1, $t3, $t4
lhu $t2, 100($t1)
sub $t2, $t2, 5
sh $t2,100($t1)

Resta 5 a un dato almacenado en la direccin esi+ecx+100:


sub word ptr [esi+ecx+100],5
#A la direccion de memoria [] le resta 5
#word ptr transforma el n 5 a 16 bits dado que sub necesita que ambas cosas sean iguales(las
direcciones de memoria son de 16)
d) Divide: $t3 = 0xb62cff / 0x1234
lui $t1, 0x00b6 #Carga en la parte alta de $t1 00B6
ori $t1, $t1, 0x2cff #Carga en la parte baja de $t1 2cFF
addi $t2, $zero, 0x1234 #Carga en $t2 1234
div $t1, $t2 #Divide $t1 entre $t2
mflo $t3 #resultado para IA32 en ebx

Divide: ebx = 0xb62cff / 0x1234


mov eax, 0b62cffh
mov ebx, 01234h
mov edx, 0 ;Cuando hacemos una divisin tenemos que poner edx a 0
div ebx

e) Traduzca a IA32 el cdigo C siguiente (use como referencia el cdigo MIPS que se
observa ms abajo):
x=4
res = 0
i=1
while (i <= x ) {
res = res + 2
i++
}

li $t0, 4 #$t0 es x #$t0 = 4


move $t1, $zero #$t1 es res #t1 = 0
addi $t2, $zero, 1 #$t2 es i #$t2 = 1
bucle: bgt $t2, $t0, fin #Si $t2 es mayor que $t0 salta a fin
addi $t1, $t1, 2 #A $t1 le suma 2
addi $t2, $t2, 1 #A $t2 le suma 1
j bucle
fin: syscall

mov eax, 4
mov ebx, 0
mov ecx, 1
bucle: cmp ecx, eax
jbe fin
add ebx, 2
add ecx, 1
jmp bucle
fin:

(REVISAR)
Ejercicios prctica 3:
Ejercicios prctica 4:
Ejercicio 1. Clculo de prestaciones.
Ejecutamos MARS y cargamos el cdigo de ejemplo, lo grabamos y lo ensamblamos (F3)
para pasar a la ventana de ejecucin.
Cdigo de ejemplo:
addi $t3,$zero,0x10010000 #$t3 = 0x10010000 (3 intrucciones)
lw $t4, 0($t3) #$t4 = [10010000], es decir, $t4 = 0 (1 instruccin)
i3: bltz $t4, i10 #Si $t4 < 0 salta a i10, por tanto no salta (1 instruccin)
add $t1,$zero,$t4 #$t1 = $t4, es decir, $t1 = 0 (1 instruccin)
lw $t2,4($t3) #$t2 = [0x10010004], es decir, $t2 = 0 (1 instruccin)
mul $s6,$t2,$t1 #$s6 = $t2 * $t1, que ser igual a $s6 = $t2 * $t4, es decir, $s6 = 0 (1 instruccin)
xor $t4,$s6,$t1 #$t4 = xor($s6, $t1), es decir, $t4 = 0 (1 instruccin)
and $t1,$s6,$t4 #$t1 = and($s6, $t4), es decir, $t1 = 0 (1 instruccin)
sw $t1, 4($t3) #$t1 = [10010004], es decir, $t1 = 0 (1 instruccin)
i10: sw $t4, 0($t3) #$t4 = [10010000], es decir, $t4 = 0 (1 instruccin)
fin: li $v0, 10 #Llamada al sistema para finalizar
syscall

a) Averiguar cuantas instrucciones tiene el programa una vez ensamblado. A la hora de


contabilizar las instrucciones debe tener en cuenta que una pseudoinstruccin puede
suponer varias instrucciones. Si el inmediato de una instruccin posee ms de 16 bits
(por ejemplo, una etiqueta), el ensamblador genera instruccin adicionales.
14 instrucciones

b) Comprobar en memoria el valor de la posicin de memoria 0x10010000 y de


0x10010004.
[0x10010000] = 0x00000000
[0x10010004] = 0x00000000

c) Razonar si el salto de i3 se llevar a cabo.


No, no se llevar a cabo, ya que saltar si $t4 es menor que cero y $t4 valdr siempre 0.
d) Suponiendo un CPI de 1 y una frecuencia de reloj de 1 MHz, calcular el tiempo de
ejecucin terico tCPU de nuestro programa.
Ahora en MARS, desde el men Tools cargamos la utilidad Instruction Counter y
cuando aparezca pulsamos sobre el botn Connect to MIPS para que comience a
contabilizar, de forma que aparecer como en la Figura 4.
Ahora ejecutemos el programa directamente sin usar el paso a paso, Run Go o F5.

Primera forma:

CPI = 1
Frecuencia de ciclo = 1 MHz = 10^6 Hz

tCPU = (Nmero de instrucciones x CPI) / Frecuencia de ciclo = 0.000014 s

Segunda forma:

CPI = 1
Frecuencia de ciclo = 1 MHz = 10^6 Hz Tiempo de ciclo = 10^-6 s

tCPU = Nmero de intrucciones * CPI * Tiempo de ciclo = 14 * 1 * 10^-6 = 0.000014 s

Ahora en MARS, desde el men Tools cargamos la utilidad Instruction Counter y cuando
aparezca pulsamos sobre el botn Connect to MIPS para que comience a contabilizar.
Ahora ejecutemos el programa directamente sin usar el paso a paso, Run Go o F5.
e) Indicar el nmero de instrucciones ejecutadas de forma general y por cada tipo de
instruccin.
El nmero de instrucciones ejecutadas de forma general : 14
R-Type: 6 [42%]
I-Type: 8 [57%]
J-Type: 0 [0%]
f) Suponiendo que las instrucciones de tipo R consumieran 3 ciclos de reloj, las de tipo I
1 ciclo y las de tipo J 3 ciclos, calcular (segn las frmulas de la Figura 2) el nmero de
ciclos del programa, el tiempo real de CPU y el CPI medio de este ejemplo.

R-Type: nCiclos = 3 / I-Type: nCiclos = 1 / J-Type: nCiclos = 3

nCiclos Programa = (nCiclos * tipoInstruccin) =


= (3 ciclos * 6 instrucciones) + (1 ciclo * 8 instrucciones) + (3 ciclos * 0 instrucciones) =
= 18 + 8 + 0 = 26

.000026 s
tCPU real = nCiclos * tiempoCiclo (apartados anteriores) = 26 ciclos * 10^-6 s = 0

CPI medio = Nmero de ciclos/ Nmero de instrucciones = (6x3+8x4)/14 = 26/14 =


= 1.85714285714

g) Repetir los apartados e y f, pero ahora usando los valores arrojados por la
herramienta Instruction Statistics y suponiendo que los valores de ciclos por tipo de
instruccin son: ALU = 1, Jump = 3, Branch = 5, Memory = 2, Other = 3.

Total de instrucciones= 14

ALU: 7 [50%]
Jump: 0 [0%]
Branch: 1 [7%]
Memory: 4 [29%]
Other: 2 [14%]

nCiclos Programa = (nCiclos * tipoInstruccin) = (1 ciclo* 7 instrucciones) + (3 ciclos *0


instrucciones) + (5 ciclos * 1 instruccin) + (2 ciclos * 4 instrucciones) + (3 ciclos * 2
instrucciones)=26 ciclos

.000026 s
tCPU real = nCiclos * tiempoCiclo = 26 ciclos * 10^-6 s = 0

CPI medio = Nmero de ciclos/ Nmero de instrucciones = 26/14 =


= 1.85714285714
Ejercicio 2. Clculo de prestaciones.
Cargue en el simulador de MIPS el siguiente cdigo. Usando los mismos valores del
apartado g del ejercicio anterior calcule:
nmero de instrucciones
nmero total de ciclos de la aplicacin
tiempo de ejecucin de CPU
CPI medio
MIPS (Millones de Instrucciones por Segundo, ver Figura 3).
# Practicas AC P1-EJ9, Universidad de Sevilla, 2012
.data
# variables globales n (tamano de los arrays) y suma:
n: .word 3 #Resevamos 32*3 = 96 bits para la etiqueta word
suma: .space 4 #Reservamos 8*4 = 32 bits para la etiqueta suma
# arrays a, b y r:
a: .word 1, 3, 5 #a[]={1, 3, 5}
b: .word 2, 4, 6 #b[]={2, 4, 6}
r: .space 12
.text
.global main
main:
# vamos a cargar en t1 el tamano de los arrays (n)
la $t1, n
lw $t1, 0($t1)
# vamos a cargar en t3 la direccion base del array a
la $t2, a
# vamos a cargar en t4 la direccion base del array b
la $t3, b
# vamos a cargar en t5 la direccion base del array r
la $t4, r
addiu $t5, $zero, 0 # suma_reg = 0
addiu $t6, $zero, 0 # i = 0
bucle: slt $t7, $t6, $t1 # i < n ?
beqz $t7, fin # si i >= n, fin
lw $t8, 0($t2) # a[i]
lw $t9, 0($t3) # b[i]
add $t8, $t8, $t9
sw $t8, 0($t4) # r[i] <-- a[i] + b[i]
add $t5, $t5, $t8 # suma_reg = suma_reg + a[i] + b[i]
addi $t2, $t2, 4 # incrementa el puntero del array a
addi $t3, $t3, 4 # incrementa el puntero del array b
addi $t4, $t4, 4 # incrementa el puntero del array r
addi $t6, $t6, 1 # ++i
j bucle
fin:
# cargamos en t0 la direccin de la variable global suma
la $t0, suma
sw $t5, 0($t0) # suma <-- suma_reg
li $v0, 10 # Llamada al sistema para finalizar
syscall
Ejercicio 3. Comparacin de algoritmos.
A continuacin se muestran dos algoritmos (a y b) que recorren una matriz
bidimensional sumando sus elementos.
--------- algoritmo a matrix 5x5 ------------
#Practica AC P3-EJ3 - MIPS
# Recorrido de una matriz 5x5 con doble bucle anidado.
.data
Tabla: .space 25
Suma: .word 0
.text
main:
addiu $t1,$zero,0 # Bucle de filas (i)
addiu $t2,$zero,0 # Bucle de columnas (j)
addiu $t3,$zero,0 # Calculo de direccion
addiu $t4,$zero,0 # registro temporal
addiu $s0,$zero,0 # Almacenaremos la Suma
Inicio:
Buclei:
Buclej:
mul $t3, $t1, 5 # Tabla[t1,t2] es Tabla [t1*5 + t2]
add $t3, $t3, $t2 #
lbu $t4,Tabla($t3) # t4 = Tabla [t1,t2])
addu $s0, $s0, $t4
addiu $t2, $t2, 1 # Incrementamos contador j
bne $t2, 5, Buclej # valores de [0..4]
addiu $t2,$zero,0 # Bucle de columnas (j)
addiu $t1, $t1, 1 # Incrementamos contador i
bne $t1, 5, Buclei # valores de [0..4]
sw $s0,Suma
fin: li $v0, 10
syscall
--------- algoritmo b matrix 5x5 ------------
#Practica AC P3-EJ3 - MIPS
# Recorrido de una matriz 5x5 con un nico bucle.
.data
Tabla: .byte 9,8 # Definimos una matrix 5x5
.space 23
Suma: .word 0
.text
main:
addiu $t1,$zero,0 # Bucle de filas (i)
addiu $t4,$zero,0 # registro temporal
addiu $s0,$zero,0 # Almacenaremos la Suma
Inicio:
Buclei:
lbu $t4,Tabla($t1) # t4 = Tabla [t1])
addu $s0, $s0, $t4
addiu $t1, $t1, 1 # Incrementamos contador i
bne $t1, 25, Buclei # valores de [0..4]
sw $s0,Suma
fin: li $v0, 10
syscall
--------------
a) Calcule para ambos usando la herramienta Instruction Statistics y los
valores del ejercicio 1.g: ninsts, nciclos, tcpu, CPI medio y MIPS
-
-------- algoritmo a matrix 5x5 ------------

Total: 279
ALU: 147 [53%]
Jump: 0 [0%]
Branch: 30 [10%]
Memory: 26[9%]
Others: 76 [27%]

--------- algoritmo b matrix 5x5 ------------

Total: 182
ALU: 80 [44%]
Jump: 0 [0%]
Branch: 25 [14%]
Memory: 26 [14%]
Other: 51 [28%]
Ejercicios prctica 5
Pi no paralelo:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int i;
double x, pi, sum = 0.0;
long numSteps = atol(argv[1]);
double step = 1.0 / (double)numSteps;
for (i=0; i<numSteps; ++i) {
x = (i+0.5)*step;
sum += 4.0/(1.0+x*x);
}
pi = step * sum;
printf("Valor de pi: %f\n", pi);
return 0;
}

Pi paralelo:

CDIGO PRACTICA 5. Solucin copiada del archivo que habia en el pc.

#include <stdio.h>
#include <stdlib.h>
#include <omp.h>

#define seed 11168


int main(int argc, char *argv[]){

int i;
double x,y;
double pi,area;
long numSteps = atol(argv[1]);

srand(seed);
for (i=0; i<numSteps; ++i) {
x= drand48();
y= drand48();

if ((x*x + y*y)<1) area++;

}
pi=4.0*area/numSteps;
printf("Valor de pi: %f\n", pi);

return 0;
}

--------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <omp.h>

#define seed 11168

int main(int argc, char *argv[]) {

double sem;
struct erand48_data randBuffer;

int i;
double x, y, area,pi;
long numSteps = atol(argv[1]);
#pragma omp parallel private(randBuffer)
{
srand48_r(omp_get_thread_num(), &randBuffer);
#pragma omp parallel for private(x,y) reduction(+:pi)
for (i=0; i<numSteps; ++i) {

erand48_r(&randBuffer, &x);
erand48_r(&randBuffer, &y);

if ((x*x + y*y)<1) area++;

}
pi=4.0*area/numSteps;
printf("Valor de pi: %f\n", pi);
return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
int main(int argc, char *argv[]) {
double pi = 0;
int dardosEnCirculo = 0;
double x;
double y;
int i;
int totalDardos = atoi(argv[1]);
for(i = 0; i < totalDardos; i++) {
x = drand48();
y = drand48();
if((x*x) + (y*y) <= 1) {
dardosEnCirculo++;
}
}
pi = 4.0 * dardosEnCirculo/totalDardos;
printf("%f\n", pi);
return pi;
}

Vous aimerez peut-être aussi