Anda di halaman 1dari 64

Fundamentos de Computadores

Tema 3 LENGUAJE ENSAMBLADOR

INTRODUCCIN ____________________________________1 Uso de un lenguaje ensamblador _____________________3 Inconvenientes del lenguaje ensamblador ______________3 Eleccin de un lenguaje ensamblador _________________3 ARQUITECTURA DEL P MIPS R2000 _________________4 Simulador de MIPS R2000: SPIM ____________________5 INSTRUCCIONES BASICAS___________________________7 Empleo de variables temporales ______________________8 Operandos ________________________________________8 Accesos a memoria _________________________________9 Accesos a estructuras de datos ______________________10 Direccionamiento de la memoria ____________________11 MODOS DE DIRECCIONAMIENTO ___________________13 Direccionamiento a registro ________________________13 Direccionamiento inmediato ________________________13 Direccionamiento base o desplazamiento ______________14 Direccionamiento relativo al contador de programa ____14 INSTRUCCIONES DE BIFURCACIN O SALTO ________15 Salto incondicional ________________________________15 Salto condicional__________________________________16 FORMATO DE LAS INSTRUCCIONES_________________19 Formato R _______________________________________19 Formato I________________________________________20
FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador Contenido - I

Formato J _______________________________________21 JUEGO DE INSTRUCCIONES ________________________22 USO DE REGISTROS Y MEMORIA ___________________28 Registros de la CPU _______________________________28 Distribucin de la memoria _________________________30 PROGRAMACIN EN ENSAMBLADOR _______________31 EJEMPLOS ________________________________________33 PROGRAMACIN MEDIANTE SUBRUTINAS __________39 Paso de parmetros _______________________________41 Preservacin de registros ___________________________41 EJEMPLOS ________________________________________42 MANEJO DE DATOS EN COMA FLOTANTE ___________47 Instrucciones para coma flotante ____________________47 LLAMADAS AL SISTEMA ___________________________50 EJEMPLO _________________________________________51 PROGRAMAS RECURSIVOS _________________________52 Estructura de la pila _______________________________52 Diseo (ejemplo factorial) __________________________53 REGULARIDAD Y ORTOGONALIDAD_________________54 EJEMPLOS: _______________________________________55 Programa que detecta cadenas capicuas.______________55 Clculo de la serie de fibonazzi. _____________________55 Conversin a formato IEEE 754. ____________________55
FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador Contenido - II

INTRODUCCIN
Instruccin: Palabra de un lenguaje que especifica alguna accin. Juego de instrucciones: Cto. de todas las instrucciones que forman un lenguaje. Lenguaje Mquina: Lenguaje de programacin que entiende un ordenador directamente. Lenguaje Ensamblador: Abstraccin de lenguaje mquina para hacerlo ms fcil de programar. Lenguaje de Alto Nivel: Lenguaje de programacin abstracto ms cercano al lenguaje humano natrual.

Lenguaje de Alto Nivel Lenguaje Ensamblador Ensamblador Lenguaje Mquina

Compilador

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

Lenguaje de alto nivel (C): int suma(int a, int b) { c=a+b; } Lenguaje Ensamblador: suma: lw $16, O($22) lw $17, O($23) add $15, $16, $17 sw $15, O($21) jr $31 Lenguaje Mquina: 01010000110011101010100010010101 01111010010101010100010111010110 01010010111011010101010101010101 10101011101100100101110101100100 01011010101100100111110100010101 01101010101110101101010101010101 10101001000101011110101010010101 01101011000101010101001011011011

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

Uso de un lenguaje ensamblador


Velocidad Tamao Carencia de compiladores

Inconvenientes del lenguaje ensamblador


Dependientes de la mquina Programas ms largos (factor de expansin) Depuracin difcil. Compiladores muy optimos.

Eleccin de un lenguaje ensamblador


CISC 1970

CISC: Complex Instruction Set Comp. RISC: Reduced Instruction Set Comp.
RISC

1980

1990

680X0, 80X86 RX000, PowerPC, Sparc, Alpha MIPS R2000

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

ARQUITECTURA DEL P MIPS R2000


Simple y regular. Bus de datos: 32bits Bus de direcciones: 32bits 4Gb de direccionamiento

MIPS R2000

Coprocesador Matemtico R2010

Memoria Principal

Bus del Sistema

$0 $1 $2 $3

hi lo

Status Cause EPC BadVAddr


$31 PC

UAL

MMU con TLB

Coprocesador 0

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

$0 $1 $2 $3

Unidad de divisin


$31

Unidad de multiplicacin

Coprocesador 1
FPU. Nmeros en coma flotante IEEE 754 Modo Usuario y Modo Ncleo Unidad de control cableada y segmentada Cache externa separada para datos y programa.

Simulador de MIPS R2000: SPIM


Programa capaz de ejecutar programas para MIPS R2000 y R3000. Mquina virtual. Instrucciones Reales y pseudoinstrucciones.

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

INSTRUCCIONES BASICAS
Instruccin aritmtica: En lenguaje de alto nivel: c:=a+b (PASCAL) Sobre MIPS R2000: add c, a, b c operando destino a primer operando fuente b segundo operando fuente La instruccin add SIEMPRE debe tener 3 op. Para sumar ms operandos: g:=a+b+c+d+e+f add g,a,b # g:=a+b add g,g,c # g:=a+b+c add g,g,d # g:=a+b+c+d add g,g,e # g:=a+b+c+d+e add g,g,f # g:=a+b+c+d+e+f (Factor de expansin) Operacin de resta o substraccin: sub c,a,b #c:=a-b

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

Empleo de variables temporales


Variables internas no necesarias para el resultado pero si para los clculos intermedios. Para generar: f:=(g+h)-(i+j)+(k-l) add t0,g,h # t0 variable temporal add t1,i,j # t1 variable temporal sub t2,k,l # t2 variable temporal sub f,t0,t1 # El orden de las anteriores add f,f,t2 # instr. no importa

Operandos
Los operandos en lenguaje mquina deben estar situados en los registros del procesador. Registros de 32 bits R2000 32 registros de 32 bits + hi + ho + PC R2010 32 registros de 32 bits Memoria Principal 4Gb como mximo El compilador debe asignar las variables a los registros. Por ejemplo f $16, g $17, h $18, etc.
FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

Accesos a memoria
Los datos se han de traer de memoria principal a los registros para poder trabajar con ellos. Los resultados pueden necesitar volcarse a memoria. Para traer un dato hay que hacer una lectura sobre memoria, instruccin lw (load word) Para volcar un dato hay que hacer una escritura sobre memoria, instruccin sw (store word) Formato: lw $8, D($17) # $8=contenido de D+$17 sw $10, D($17) # En dir. D+$17 alamcena $10 D+$17 direccin efectiva

MP MIPS R2000 $8 $10 $17 = 0 D

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

Accesos a estructuras de datos


PROGRAM ejemplo VAR x,k,i: INTEGER; V: ARRAY[0..999] OF INTEGER; BEGIN x:=k-(V[i]+V[i]); V[i+1]:=k+V[i]; END. Como acedemos al elemento i del vector: Suponemos i almacenada en $17 lw $10, Vinicio($17) # $17 se le llama reg. indice
MIPS R2000 $10 $17 = i ... V (dir. inicio) $17 V[i] MP

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

10

Direccionamiento de la memoria
Direccionamiento por palabra, media palabra y byte. Palabras (32 bits, 4bytes): 0, 4, 8, 12, 232-4 Medias pal. (16 bits, 2bytes): 0, 2, 4, 6, 232-2 Bytes (8 bits, 1bytes): 0, 1, 2, 3, 232-1
Memoria Principal 3 7 11 2 6 10 1 5 9 0 4 8

D+1 D+6

D D+4 D+8

*Con D mltiplo de 4
Dir. Media Palabra 0 0 (Half-Word 0) 1 2 3 4 Palabra 4 (Word 4) 5 6 7 8 9 .... Media Palabra 2 (Half-Word 2) Media Palabra 4 (Half-Word 4) Dir. Byte 0 0 Byte 1 1 2 3 4 5 6 7 8 9 .... Byte 2 Byte 3 Byte 4 Byte 5 Dir. 0 1 2 3 4 5 6 7 8 9 ....

Palabra 0 (Word 0)

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

11

Del ejemplo: Para acceder a V[i], siendo V un vector de palabras, $17 debe contener i*4 y no i. V[i] ? Elemento nmero i del vector V. V ? Vector de palabras. V[i] ? Palabra nmero i. Qu direccin tendr V[i]?
Dir. V-1 V = V[0] = V V+1 V+2 V+3 V[1] = V+4 .... V[i] = V+(i*4) V+(i*4)+1 V+(i*4)+2 V+(i*4)+3 ....

Para codificar: V[i+1]:=V[i]+k; lw $10, Vinicio($17) # $17 i*4 add $10, $18, $10 add $17, $17, $21 # $18 contiene k # $21 contiene 4

sw $10, Vinicio($17) # V[i+1]:=k+V[i]

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

12

MODOS DE DIRECCIONAMIENTO
Modos de acceder a los operandos de una instruccin. Repercuten en el modo de acceder a los datos. Modo real: Sumar algo al contenido de un registro. Modo virtual: Segn sea el algo: Direccionamiento a registro Direccionamiento inmediato Direccionamiento base o desplazamiento Direccionamiento relativo a PC

Direccionamiento a registro
El dato esta ubicado en el registro sub $8, $10, $22 lw $10, Vinicio($17)

Direccionamiento inmediato
El operando es un valor constante Inicializacines o operaciones con ctes. Instrucciones en versin inmediata: addi $17, $17, 4 # inmediate add

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

13

Direccionamiento base o desplazamiento


Normalmente se emplea para accesos a memoria La direccin efectiva se obtiene sumando una cantidad ms el contenido de un registro La cantidad se codifica con la instruccin. Dos posibles interpretaciones: lw $10, Vinicio($17) lw $10, 12($16) #Acceso al valor $17/4 #Acceso al valor 3 #En $16 esta Vinicio

Direccionamiento relativo al contador de programa


Normalmente usado en saltos. bne $21, $8, seguir seguir es una etiqueta La direccin de salto se calcula como un valor aadido (o restado) al contador de programa actual Este valor lo calcula el ensamblador: etiqueta: addi $5, $8, 78 # Ir a seguir si $8<>$21

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

14

INSTRUCCIONES DE BIFURCACIN O SALTO


Tipos: Salto incondicional Salto condicional

Salto incondicional
Instruccin: j (jump) Operando: Direccin destino. Valor concreto o etiqueta j 2300 j etiqueta #Salta a la direccin 2300 #Salta a la direccin de la etiqueta

Instruccin: jr (jump register) Operando: Registro que contiene la dir. de salto. Direccionamiento indirecto a registro jr $12 #Salta a direccin indicada por $12

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

15

Salto condicional
Salta si se produce alguna condicin Implementa IFTHENELSE

beq $7, $12, etiqueta bne $7, $12, etiqueta

#Salta si $7 = $12 #Salta si $7<>$12

Comparacin de desigualdad: slt $8, $19, $22 # set on less than

Si $19<$22 entonces $8=1 sino $8=0 Para realizar un salto si x < y (x $8, y $9) slt $10, $8, $9 bne $10, $0, menor

MIPS: El registro $0 es de solo lectura y siempre contiene un 0.

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

16

Algunas codificaciones sencillas: SENTENCIA IF (SI) Suponemos i, j, a, h $16 - $19 SI (i=j)ENTONCES a:=a+h; a:=a+j; bne $16, $17, L1 add $18, $18, $19 L1: add $18, $18, $17 BUCLE REPEAT UNTIL (REPETIR HASTA) Variables: g, h, i, j $17 - $20 A es un vector de enteros (de palabras) Suponemos (como ocurre en C) que A=&A[0]=Ainicio REPETIR g:=g+A[i]; i:=i+j; HASTA (i=h) bucle: multi $9, $19, 4 lw $8, A($9) add $17, $17, $8 add $19, $19, $20 bne $19, $18, bucle

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

17

SENTENCIA WHILE (MIENTRAS) Suponemos i, x $22 - $23 i:=1 MIENTRAS (i<35) HACER x:= x-2; i:= i+5; FIN DEL MIENTRAS x:= x+18; addi $22, $0, 1 slti $10, $22, 35 beq $10, $0, salir addi $23, $23, -2 addi $22, $22, 5 j bucle addi $15, $15, 18

bucle:

salir:

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

18

FORMATO DE LAS INSTRUCCIONES


Cada instruccin ocupa 32 bits (1 palabra) 3 tipos de codificaciones decodificador de instrucciones ms simple

Formato R
Instrucciones con todos los operandos en registros Campos de la instruccin: 6 bits 5 bits 5 bits 5 bits 5 bits 6 bits

1 y ltimo: Tipo de operacin a realizar 2: Primer operando fuente 3: Segundo operando fuente 4: Destino 5: Desplazamiento en op. de desplazamiento op rf1 rf2 rd desp func

Por ejemplo: add $15, $2, $3

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

19

000000

00010

00011

01111

00000

100000

Formato I
Instrucciones de carga/almacenamiento Instrucciones de salto condicional Instrucciones con datos inmediatos Se utilizan 16 bits para codificar dato o desplazamiento Formato: op 6 bits rf 5 bits rd 5 bits inm 16 bits

Carga: lw $3, Ainicio($13) Salto condicional: beq $1,$2, salir El desplazamiento de salir son palabras salir lo calcula el compilador Si el salto excede el desplazamiento mximo: beq $18, $19, Etiqueta bne $18, $19, aux j etiqueta aux:

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

20

Formato J
Instrucciones de salto incondicional (no todas) Formato: op 6 bits direccin 26 bits

direccin expresada en palabras Salto mximo 228 bytes = 256Mb Salto mayor: Instruccin jr registro con direccin. Programas no relocalizables

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

21

JUEGO DE INSTRUCCIONES
Instrucciones reales Pseudoinstrucciones () ARITMTICO-LGICAS: add Rdest, Rsrc1, Src2 Suma (con signo) addi Rdest, Rsrc1, Imm Suma inmediata (c.s.) addu Rdest, Rsrc1, Suma (sin signo) Src2 addiu Rdst, Rsrc1, Imm Suma inmediata (s.s.) sub Rdest, Rsrc1, Src2 Resta (con signo) subu Rdest, Rsrc1, Resta (sin signo) Src2 div RSrc1, RSrc2 divu RSrc1, RSrc2 Divisin (con signo) Divisin (sin signo)

cociente en registro lo - resto en reg. hi mult Rsrc1, Rsrc2 multu Rsrc1, Rsrc2 Multiplicacin (c.s.) Multiplicacin (s.s.)

parte baja resultado en reg. lo - alta en reg. hi

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

22

nor Rdst, Rsrc1, Src2 or Rdst, Rsrc1, Src2 ori Rdst, Rsrc1, Imm and Rdst, Rsrc1, Src2 andi Rdst, Rsrc1, Imm xor Rdst, Rsrc1, Src2 xori Rdst, Rsrc1, Imm Sll Rdst, Rsrc1, Src2 srl Rdst, Rsrc1, Src2 sra Rdst, Rsrc1, Src2

Nor (Or negada) Or Or AND lgico AND inmediata Xor (Or exclusiva) Xor inmediata Desplazamiento a izq. Desp. a derecha Desp. aritmtico dcha.

En Src2 esta el nm. de bits a desplazar MANIPULACIN DE CONSTANTES li Rdst, Imm Rdst Imm () lui Rdst, Imm Rdst(parte alta) Imm COMPARACIN slt Rdst,Rsrc1, Src2 slti Rdst, Rsrc1, Imm

< < inmediata

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

23

sltu Rdst,Rsrc1, Src2 < (sin signo) sltui Rdst, Rsrc1, Imm < inmediata (sin signo) Rdst=1 si Rsrc1<Src2(o Imm), en otro caso Rdst=0 SALTO CONDICIONAL E INCONDICIONAL Saltos condicionales: Campo 16 bits con signo 215-1 instrucciones hacia adelante y 215-1 hacia atrs Salto incondicional: Campo con 26 bits. beq Rsrc1, Rsrc2, Etq Salto si igual bne Rsrc1, Rsrc2, Etq Salto si distinto bgtz Rsrc, Etiq bgez Rsrc, Etiq bgezal Rsrc, Etiq bltz Rsrc, Etiq blez Rsrc, Etiq blezal Rsrc, Etiq j etiqueta jal etiqueta jalr Rsrc jr Rsrc Salto si > 0 Salto si >= 0 Salto y enlaza si >= 0 Salto si < 0 Salto si <= 0 Salto y enlaza si <= 0 Salto incondicional Salto incond. y enlaza S. inc. a reg. y enlaza Salto incond. a reg.

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

24

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

25

CARGA la Rdest, ident lb Rdest, direccin lbu Rdest, direccin lh Rdest, direccin lhu Rdest, direccin lw Rdest, direccin ld Rdest, direccin ALMACENAMIENTO sb Rsrc, direccin sh Rsrc, direccin sw Rsrc, direccin sd Rsrc, direccin

Carga direccin () Carga byte (ext. signo) Carga byte (sin ext.) Carga media-pal.(ext.) Carga media-pal.(s.e.) Carga palabra Carga doble palabra()

Almacena byte bajo Alm. media-pal. baja Alm. palabra Alm. doble palabra

En las instrucciones de carga y almacenamiento: Direcciones para bytes: cualquiera. Direcciones para medias pal.: mltiplos de dos (pares). Dir. para palabras: mltiplos de 4. Dir. para dobles palabras: mltiplos de 8.

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

26

MOVIMIENTO move Rdest, Rsrc mfhi Rdest mflo Rdest mthi Rdest mtlo Rdest

Rdest Rsrc () Rdest hi Rdest lo hi Rdest lo Rdest

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

27

USO DE REGISTROS Y MEMORIA


Registros de la CPU
32 registros de propsito general $n registro n $0=0 siempre Identificadores y usos convenidos (tabla) $1, $26, $27 el ensamblador y S.O. $4-$7 Paso primeros 4 arg. a subrutinas $8-$15, $24, $25 Temporales $16-$23 Valores preservados en llamadas $29 Puntero de pila $30 Puntero de marco $31 Direccin de retorno (jal) $28 Puntero a datos globales (64K): heap

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

28

Nmero Nombre Uso


0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 $zero $at $v0 $v1 $a0 $a1 $a2 $a3 $t0 $t1 $t2 $t3 $t4 $t5 $t6 $t7 $s0 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $t8 $t9 $k0 $k1 $gp $sp $fp $ra Constante 0 Reservado para el ensamblador Evaluacin de expresiones Evaluacin de expresiones Argumento 1 Argumento 2 Argumento 3 Argumento 4 Temporal (no preservado entre llamadas) Temporal (no preservado entre llamadas) Temporal (no preservado entre llamadas) Temporal (no preservado entre llamadas) Temporal (no preservado entre llamadas) Temporal (no preservado entre llamadas) Temporal (no preservado entre llamadas) Temporal (no preservado entre llamadas) Salvado temporalmente (preservado entre llamadas) Salvado temporalmente (preservado entre llamadas) Salvado temporalmente (preservado entre llamadas) Salvado temporalmente (preservado entre llamadas) Salvado temporalmente (preservado entre llamadas) Salvado temporalmente (preservado entre llamadas) Salvado temporalmente (preservado entre llamadas) Salvado temporalmente (preservado entre llamadas) Temporal (no preservado entre llamadas) Temporal (no preservado entre llamadas) Reservado para el ncleo del S.O. Reservado para el ncleo del S.O. Puntero al rea global (global pointer) Puntero de pila (stack pointer) Puntero de marco (frame pointer) Direccin de retorno (return address)

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

29

Distribucin de la memoria
Organizacin convencional 3 partes: Segmento de cdigo: 0x400000 (text segment) Segmento de datos: 0x10000000 (data segment) Segmento de pila: 0x7FFFFFFF (stack segment) $29
0x7FFFFFFF

Segmento de pila

Datos dinmicos Datos estticos Segmento cdigo Reservado


0x10000000 0x00400000 0x00000000

Ordenamiento de los bytes: Little endian


31

1 00

3 Big endian
FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

30

31

2 30

PROGRAMACIN EN ENSAMBLADOR
1 instruccin por lnea 4 campos: Etiqueta (opcional) Cdigo operacin Operandos Comentario (opcional) Identificadores: Caracteres alfanumricos + _ + . Palabras reservadas Etiquetas = identificador+: Directivas: Instrucciones SOLO para el ensamblador

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

31

Directiva
Alinea el siguiente dato en 2n bytes. Con n=0, se desactiva la alineacin de .half, .word, .float, .double hasta la siguiente directiva .data .ascii str Almacena la cadena str en memoria sin car. nulo. .asciiz str Almacena str en memoria + car. nmero 0 (NULL) .byte b1, ,bn Almacena los bn en bytes de memoria consecutiva .data <addr> Almacena los elementos declarados a continuacin de la directiva a partir de la dir. ADDR en el segmento de datos. Si no aparece se toma la dir. por defecto. .double d1, ,dn Almacena los dn doble words de coma flotante (64 bits) consecutivamente en memoria. .end Fin del programa .float f1, ,fn Almacena los fn valores de coma flotante (32 bits) consecutivamente en memoria. .global smbolo Smbolo declarado como global. Se puede referenciar desde otros archivos. .half h1, ,hn Alamcena las hn medias palabras (16 bits) consecutivamente en memoria. .space n n bytes reservados en el segmento de datos .text <addr> Almacena los elementos declarados tras esta directiva en el segmento de cdigo a partir de la direccin ADDR. Estos elementos solo pueden ser palabras (.word) o instrucciones. Si no aparece ADDR se toma la direccin por defecto. .word w1, ,wn Almacena las wn palabras (32 bits) en posiciones consecutivas de memoria.

.align n

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

32

EJEMPLOS
Ejemplo 1: Suma de los primeros 200 nmeros. En PASCAL: i:=0; suma:=0; REPETIR i:=i+1; suma:=suma+1; HASTA QUE(i>=200) i $8, suma $9
.data 0x10000000 .text .global __start __start: addi $8,$0,0 addi $9,$0,0 repeat: addi $8,$8,1 add $9,$9,$8 slti $10,$8,200 bne $10,$0,repeat .end #seg. de datos #seg. Cdigo #Inicio del prog. #i:=0 #suma:=0 #i:=i+1 #suma:=suma+i #$10:=1 si i<200 #Si $10=1 ir rep.

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

33

Ejemplo 2: Programa que cuenta la longitud de la palabra Fundamentos+NULL almacenada a partir de la direccin 0x10000000. En $21 se debe almacenar la cadena.
.data 0x10000000 #Seg. de datos .asciiz Fundamentos .text .global inicio #En SPIM __start inicio: lui $20, 0x1000 ori $20, 0x0000 addi $21, $0, 0 bucle: lb $19, 0($20) beq $0, $19, fin addi $20, $20, 1 addi $21, $21, 1 j bucle fin: .end #Carga parte alta #Carga parte baja #Inicializamos a 0 #Lectura byte de la cad. #Si es 0 (NULL), fin #Inc. para leer sig. car #Inc. longitud

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

34

Ejemplo 3: Programa que copia la longitud de la palabra Fundamentos + NULL almacenada a partir de la direccin 0x10000000 a la direccin 0x100020A0
.data 0x10000000 #Seg. de datos .asciiz Fundamentos .data 0x100020A0 #Direccin destino .space 12 (11+1) #Espacio para copia .text .global inicio #En SPIM __start inicio: lui $20, 0x1000 ori $20, 0x0000 lui $21, 0x1000 ori $21, 0x20A0 bucle: lb $19, 0($20) sb $19, 0($21) beq $0, $19, fin addi $20, $20, 1 addi $21, $21, 1 j bucle fin: .end #Carga parte alta #Carga parte baja #Parte alta destino #Parte baja destino #Lectura byte de la cad. #Copiamos caracter #Si es 0 (NULL), fin #Inc. para leer sig. car #Siguiente car. destino

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

35

EJEMPLO 4: Programa que cuenta los bits a 1 en una palabra de 32 bits Palabra en registro $20. Resultado en registro $21.
.data 0x10000000 .text .global __start inicio: add $21, $0, $0 beq $20, $0, fin addi $18, $0, 1 rotar: beq $18, $0, fin and $19, $20, $18 sll $18, $18, 1 beq $19, $0, rotar addi $21, $21, 1 j rotar fin .end #Contador a 0 #Si no hay 1s, fin #Ponemos 1 en $18 #32 desplazamientos #Extraer bit i-essimo #Desplazar a la izq. #Bit 0, no contamos #Incrementamos cuenta

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

36

EJEMPLO 5: Programa en ensamblador que concatene dos cadenas acabadas en NULL. El algoritmo debe copiarlas en una cadena destino. Primero copia una y despus copia la segunda a continuacin. Para referenciar una posicin de memoria usaremos etiquetas en lugar de usar lui y ori. Las etiquetas apuntan al inicio de las cadenas. Las direcciones las genera el ensamblador.
.data 0x10000000 .asciiz ensamblador .asciiz ejemplo .space 19 .text .global __start #Leer caracter cad. 1 #Si es 0, leer cad. 2 #Copiamos a destino #Incrementamos indice #Seguir leyendo cad. 1 #Lectura seg. cadena #Leer carcter #Copiar a destino #Con NULL acabamos #Incrementamos indice 1 #Inc. indice 2

cad1: cad2: dest:

inicio: add $16,$0,$0 lcad1: lb $17, cad1($16) beq $17,$0,flcad1 sb $17,dest($16) addi $16,$16,1 j lcad1 flcad: add $18,$0,$0 lcad2: lb $17,cad2($18) sb $17,dest($16) beq $17,$0, fin addi $16,$16, 1 addi $18, $18, 1 j lcad2 fin: .end

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

37

EJEMPLO 6: Dado un vector de 6 enteros de 32 bits en 0x10000000, no indique cuantos elementos son mayores, menores e iguales que el ltimo elemento. Ubicar el resultado en memoria, despus de los elementos del vector y del nmero de elementos.
.data 0x10000000 vector: .word 34, 21, 10, 5, 3, 10 nelem: .word 6 mayor: .word 0 menor: .word 0 igual: .word 0 .text .global __start inicio: lw $20,nelem($0) addi $16,$0,4 mult $20,$16 mflo $16 addi $16,$16,-4 lw $8,vector($16) add $18,$0,$0 bucle: addi $20,$20,-1 lw $21,vector($18) addi $18,$18,4 si: slt $7,$21,$8 bne $7,$0,ent j snsa ent: lw $9,menor($0) addi $9,$9,1 sw $9,menor($0) #Leemos nm. elementos #Tamao en bytes #Movemos lo a $16 #Indice ltima coponente #Referencia en $8 #Indice para vector #Dec. nmero elementos #Leemos elemento vector #Inc. indice #$21<$8? #Es menor, ir a ent #No menor, igual o may? #Leer menores #Incrementar menores #Escribir

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

38

j finb snsa: beq $21,$8,igua lw $9,mayor($0) addi $9,$9,1 sw $9,mayor($0) j finb lw $9,igual($0) addi $9,$9,1 sw $9,igual($0) beq $20,$0,fin j bucle .end #Son iguales? #Mayor. Leer mayores

igua: finb: fin:

#Leemos iguales

PROGRAMACIN MEDIANTE SUBRUTINAS


MIPS da soporte a las subrutinas mediante la instruccin jal (jump and link). Almacena en $31 la direccin de retorno (PC) Sintaxis: jal Direccin Para finalizar: jr $31
$31:=D (PC+4) PC:=rutina rutina D-4 D jal rutina instruccin jr $31

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

39

Llamadas anidadas? Solucin: Usar la pila ($29) Almacenar en pila: Apilar o push Sacar de pila: Desapilar o pop Por ejemplo:

Prog. principal

Rutina 1

Rutina 2

Rutina 3

El compilador generar:
inicio: jal Rut1 j fin Rut1: addi $29,$29,-4 sw $31, 0($29) jal Rut2 lw $31,0($29) addi $29,$29,4 jr $31 igual que Rut1 jr $31 #No hace falta apilar porque no #hay llamada a subrutina #Apilar #Guardar dir. retorno #Recuperar direccin #Desapilar

Rut2: Rut3:

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

40

fin:

.end

Paso de parmetros
Por convencin se usan $4, $5, $6, $7 Para ms parmetros se usa la pila

Preservacin de registros
Con rutinas anidadas, que pasa con $4$7? Solucin: Usar la pila Cuando se llama a una subrutina, que ocurre con los valores actuales de los registros? Dos convenios: Guardar invocadora (caller save). Guardar invocada (callee save). En MIPS se usa el convenio callee save.

Guardar Salto Restaurar

Guardar Rutina Salto Rutina Restaurar

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

41

EJEMPLOS
Uso de subrutinas
PROCEDURE intercambia(var v:vector;k:integer); VAR temp:integer; BEGIN temp:=v[k]; v[k]:=v[k+1]; v[k+1]:=temp; END.

Registros: $15temp, $4v, $5k Algoritmo de ordenamiento de la burbuja


PROCEDURE ordena(var v:vector; n:integer); VAR i,j:integer; BEGIN FOR i:=0 TO n-1 DO BEGIN j:=i-1; WHILE(j>=0) AND (v[j]>v[j+1]) DO BEGIN intercambia(v,j); j:=j-1; END; END; END.

Registros: $19i, $17j, $4v, $5n PASOS A SEGUIR: 1.Generar cuerpo de la rutina

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

42

2.Salvar los registros usados

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

43

Rutina de intercambio de elementos del vector: 1.- Cuerpo:


2 addi $14,$0,4 mult $5,$14 mflo $2 add $2,$4,$2 lw $15, 0($2) lw $16, 4($2) sw $16, 0($2) sw $15, 4($2) #$14=4 #lo=k*4 #$2=lo (k*4) #$2=v+(k*4) v[k] #$15(temp)=v[k] #$16=v[k+1] #v[k]=$16=v[k+1] #v[k+1]=$15=temp #Espacio para 4 pal #Apilar $2 #Apilar $14 #Apilar $15 #Apilar $16 #Desapila $2 #Desapila $14 #Desapila $15 #Desapila $16 #Vaciar pila #Fin de subrutina

2.- Salvado de registros ($2,$14,$15,$16)


inter: addi $29,$29,-16 1 sw $2, 0($29) sw $14, 4($29) sw $15, 8($29) sw $16, 12($29) 3 lw $2, 0($29) lw $14, 4($29) lw $15, 8($29) lw $16, 12($29) addi $29,$29,16 jr $31

Recuperacin de registros y retorno de subrutina

Rutina de ordenamiento de la burbuja: Necesita guardar los parmetros en otros registros Hay que implementar dos bucles anidados El bucle interno tiene dos condiciones

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

44

1.-Cuerpo:
ordena: (4)Apilar registros usados 5 add $18,$4,$0 #Copia parmetro v add $20,$5,$0 #Copia parmetro n add $19,$0,$0 #i:=0 addi $21,$0,4 #$21=4 for: slt $8,$19,$20 #$8=0 si i>=n beq $8,$0,exitf #Salir si i>=n addi $17,$19,-1 #j:=i-1 while: slti $8,$17,0 #S8=1 si j<0 bne $8,$0,exitw #Salir si j<0 mult $17,$21 #lo=j*4 mflo $15 #$15=lo (j*4) add $16,$18,$15 #$16=v+j lw $24,0($16) #$24=v[j] lw $25,4($16) #$25=v[j+1] slt $8,$25,$24 #$8=0 si $25>=$24 beq $8,$0,exitw #Salir si v[j+1]>=v[j] add $4,$18,$0 add $5,$17,$0 jal inter #Parmetro v=v #Parmetro k=j

addi $17,$17,-1 #j:=j-1 j while #Repetir bucle while exitw: addi $19,$19,1 #i:=i+1 j for #Repetie bucle for exitf: (6)Desapilar todos los registros apilados jr $31 #Retorno de subrutina

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

45

2.-Apilar - desapilar: $8,$15-$21, $24, $25, $31: total 11


4 addi $29,$29,-44 sw $8,0($29) sw $31,40($29) lw $8,0($29) addi $29,$29,44 #Espacio para 11 pal. #Apilar $8 #Apilar $31 #Desapilar $8 #Liberar espacio pila

Programa principal que llama a la rutina de la burbuja


.data .word .word .word 0x10000000 0x10000004 72,50,8 20,15

v:

#Direccin vector #Vector

.text .global inicio inicio: lw $4,v($0) addi $5,$0,5 jal ordena j fin CODIGO DE LAS RUTINAS fin: .end #Inicializa parmetro v #Inicializa parmetro n #Burbuja #Salto al final

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

46

MANEJO DE DATOS EN COMA FLOTANTE


Standar IEEE 754 Formatos simple (32 bits) y doble precisin (64 bits) Datos manejados por FPU 32 registros de 32 bits. Doble precisin: 2 registros consecutivos. Instrucciones de coma flotante SOLO con reg. pares Registro de control y estado Idea similar a procesador: carga y almacenamiento Operaciones en FPU y P simultneas Instrucciones con sufijo d (doble) y s (simple)

Instrucciones para coma flotante


FRdest, FRsrc1 y FRsrc2 registros de FPU PARES ($fn)

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

47

add. FRdest, FRsrc1, FRsrc2 d (doble precisin) s (simple precisin) sub. FRdest, FRsrc1, FRsrc2 abs. FRdest, FRsrc Valor absoluto de FRsrc mult. FRdest, FRsrc1, FRsrc2 div. FRdest, FRsrc1, FRsrc2 l. FRdest, direccion () s. FRdest, direccion () Carga y almacenamiento mfc1 Rdest,FRscr Mueve dato de FPU a CPU mtc1 Rsrc,FRdest Mueve dato de CPU a FPU mfc1.d Rdest,FRscr () Mueve datos de FRscr y FRscr+1 a Rdest y Rdest+1 mtc1.d Rsrc,FRdest () Idem pero de CPU a FPU c.x. FRscr1,FRscr2 Comparacin de FRscr1 y FRscr2. Se activa el bit correspondiente del reg. de estado del coprocesador. El bit depende de la condicin x: eq, neq, lt, le, gt, ge. bc1t direccion #Salto si TRUE bc1f direccion #Salto si FALSE
FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

48

Ejemplo: Suma de los elementos de un vector en coma flotante de simple precisin. El vector empieza en 0x10000004.
.data 0x10000000 tam: .word 4 vector: .float 3.1415, 2.7182 .float 1.0e+2, 6.5e-1 res: .float 0.0 .text .globl __start inicio: addi $15,$0,0 #Indice addi $17,$0,0 #Contador lw $16,tam($0) #Tamao del vector mtc1 $0, $f2 #0 a f2 (temporal) bucle: l.s $f4,vector($15)#Leemos elem $15 vector add.s $f2,$f2,$f4 #Sumamos elemento addi $15,$15,4 #Increm. indice addi $17,$17,1 #Increm. contador slt $8,$17,$16 #Final? bne $8,$0,bucle #$8=1 implica $17<$16 s.s $f2,res($0) #Almacenar resultado fin: .end

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

49

LLAMADAS AL SISTEMA
Son llamadas al sistema operativo Facilitan la tarea del programador Ofrecen servicios como imprimir por pantalla o introducir nmeros y caracteres por teclado syscall Tipo de llamada en $2 ($v0) Parmetros en $4$7 ($f12 con coma flotante) Ejecutar syscall. El resultado se devuelve en $2 o $f0 Servicio
print_int print_float print_double print_string read_int read_float read_double read_string sbrk exit

Cdigo
1 2 3 4 5 6 7 8 9 10

Parmetros
$4=entero $f12=float $f12=doble $4=dir. cadena

Resultado

$2 entero $f0 float $f0 doble $2 direccin

$4=dir. buffer, $5= longitud $4=desplazam.

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

50

EJEMPLO
Programa que calcula la potencia de dos nmeros: ab Para ensamblador, deberemos imprimir las cadenas y leer los datos que el usuario introduzca con llamadas al sistema.
.data 0x10000000 .asciiz \nDame la base real: .asciiz \nDame el exponente entero: .asciiz \nEl resultado es: .text .global inicio inicio: addi $2,$0,4 #Cdigo impresin la $4, cad1 #direccin de cadena1 syscall #Impresin addi $2,$0,6 #Cod. lectura float syscall #Lectura base addi $2,$0,4 #Cod. impresin la $4, cad2 #direccin cadena2 syscall #Impresin addi $2,$0,5 #Cod. lectura entero syscall #Lectura exponente cad1: cad2: cad3: mfc1 $4,$f0 add $5,$0,$2 jal pot mtc1 $2,$f12 addi $2,$0,4 la $4,cad3 syscall addi $2,$0,2 syscall addi $2,$0,10 syscall .end pot: addi $29,$29,-12 sw $9,0($29) #Pasamos la base a $4 #Exponente en $5 #Llamada a rutina #Resultado de $2 a $f12 #Cdigo impresin #Direccin cadena3 #Impresin #Escritura float #Escribimos $f12 #Cod. salida programa

#Hacemos sitio en pila #Apila $9

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

51

for:

exif:

s.s $f4, 4($29) #Apila $f4 s.s $f6, 8($29) #Apila $f6 addi $9,$0,2 #i:=2 mtc1 $4,$f4 #aux:=base mtc1 $4,$f6 #$f6:=base slt $10,$5,$9 #i>exponente? bne $10,$0,exif #salir si i>exponente mul.s $f4,$f4,$f6 #aux:=aux*base addi $9,$9,1 #i:=i+1 j for mfc $2,$f4 #Devolvemos res en $2 lw $9,0($29) #Desapilar $9 l.s $f4, 4($29) #Desapilar $f4 l.s $f6, 8($29) #Desapilar $f6 addi $29,$29, 12 #Restaurar pila jr $31 #Fin subrutina

PROGRAMAS RECURSIVOS
Rutina que se llama a si misma En cada llamada se usan los mismos registros y direcciones de memoria Uso adecuado de la pila

Estructura de la pila
Es necesario almacenar en la pila cierta informacin MIPS ofrece un modelo para hacer las llamadas de una forma uniforme, que indica la estructura que debe tener la pila: 1.Argumentos de la subrutina (ms de 4)

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

52

2.Registros que se modifican en la subrutina y cuyo valor se debe mantener 3.Variables locales. $fp ($30) + Argumento 5 Argumento 6 ...
Registros guardados Variables locales $sp ($29) -

Diseo (ejemplo factorial)


FUNCTION factorial(n:integer):integer; BEGIN IF(n<>0)THEN factorial:=n*factorial(n-1); ELSE factorial:=1; END;

Cada llamada debe guardar su propia pila. Suponemos que tenemos el entero en $2 y que ya lo hemos leido del usuario. El parmetro de factorial lo pasamos en $4:
addi $4,$2,0 jal fact fact: addi $29,$29,-8 sw $4,4($29) sw $31,0($29) #Inicializacin y lectura #Parmetro introducido a $4 #Llamada principal #Imprimir y terminar #Espacio para 2 palabras #Almacena parmetro ($4) #Almacena dir. retorno

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

53

lw $2,4($29) bgtz $2,seguir addi $2,$0,1 j volver seguir: lw $3,4($29) addi $4,$3,-1 jal fact lw $3,4($29) mult $2,$3 mflo $2 volver: lw $31,0($29) addi $29,$29,8 jr $31

#Lectura argumento n ? #Si n>0 llamarse #Un 1 como resultado #fin de recursin #Lectura argumento n #Parmetro n-1 #Llamada recursiva #Lectura argumento n #n*factorial(n-1) ($2) #Resultado parcial #Direccin de retotno #Restaurar pila #Retorno

REGULARIDAD Y ORTOGONALIDAD
Regularidad: Conjunto de instrucciones uniformes sin casos especiales. Simplifica la programacin. Ortogonalidad: Cualquier operacin se puede usar con cualquier operando y cualquier modo de direccionamiento. Los dos conceptos estn muy unidos.

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

54

EJEMPLOS:
Programa que detecta cadenas capicuas. Clculo de la serie de fibonazzi. Conversin a formato IEEE 754.

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

55

buffer: cad: si: no:

.data .space 100 .asciiz "\nIntroduce la cadena:" .asciiz "\nLa cadena es capicua" .asciiz "\nLa cadena no es capicua" .text .globl __start la $4,cad addi $2,$0,4 syscall addi $2,$0,8 la $4,buffer addi $5,$0,100 syscall add $11,$0,$0 addi $12,$0,10 lb $10,0($4) beq $10,$12,finlong addi $4,$4,1 addi $11,$11,1 j long beq $11,$0,fin addi $4,$4,-1 la $5,buffer lb $10,0($4) lb $12,0($5) bne $10,$12,finno addi $4,$4,-1 addi $5,$5,1 addi $11,$11,-2 slti $13,$11, 2 bne $13,$0,finsi j bucle #Clculo de la longitud

__start:

long:

finlong:

#Cadena vacia #Apuntar al ultimo char.

bucle:

#$13=1 si $11<2 --- fin

finsi:

la $4,si addi $2,$0,4 syscall j fin la $4,no addi $2,$0,4 syscall

finno:

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

56

fin:

addi $2,$0,10 syscall

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

57

.data .text .globl __start __start: addi $2,$0,5 syscall add $4,$0,$2 jal fibon j fin fibon: addi $29,$29,-12 sw $10,8($29) sw $4,4($29) sw $31,0($29) beq $4,$0,zero slti $10,$4,2 bne $10,$0,un addi $4,$4,-1 jal fibon add $10,$0,$2 lw $4,4($29) addi $4,$4,-2 jal fibon add $2,$2,$10 jr finfibo zero: add $2,$0,$0 jr finfibo addi $2,$0,1 lw $31,0($29) lw $4,4($29) lw $10,8($29) addi $29,$29,12 jr $31 add $4,$0,$2 add $2,$0,1 syscall addi $2,$0,10

un: finfibo:

fin:

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

58

syscall

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

59

flotant: string: nmero cad: return:

.data .float 103.487 .byte 0,0,0,0,0,0,0,0,0

#Espacio para almacenar el

.asciiz "\nIntroduce el nmero en coma flotante:" .asciiz "\nEl nmero en formato IEEE754 es (en Hex.):\n" .text .globl __start la $4,cad addi $2,$0,4 syscall addi $2,$0,6 syscall mov.s $f12, $f0 addi $2, $0, 2 syscall

__start:

#Impresin de la cadena cad

#Lectura de nmero en coma flotante #Impresin del nmero

mfc1 $4, $f0 #Llevmos el nmero del copro a la addi $5, $0, 16 #CPU para su visualizacin addi $6, $0, 7 bucle: divu $4, $5 #Conversin a hexadecimal mfhi $7 #Dividiendo por 16 sucesivamente sb $7, string($6) #Y almacenando los resultados en addi $6, $6, -1 #el espacio reservado en orden mflo $4 #inverso: primera divisin dgito bne $4,$0,bucle #menos significativo add $6, $0, $0 addi $10, $0, 8 loop: lb $4, string($6) #Conversin de la cadena de digitos slti $5, $4, 10 #hex. en sus correspondientes bne $5, $0, menorde10 #caracteres ASCII para poderlos #Imprimir majorde10:addi $4, $4, 55 #Si el dgito es mayor de 9 j finloop #sumamos 55 a su valor para convertir #en los caracteres de A a F. menorde10:addi $4, $4, 48 #Si esta entre 0 y 9, sumamos 48 para #Convertir en caracteres 0 a 9. finloop: sb $4, string($6) addi $6, $6, 1 beq $6, $10, fin #Repetimos para todos los dgitos j loop fin: la $4,return addi $2,$0,4 syscall #Imprimimos la cadena return

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

60

la $4,string addi $2,$0,4 syscall addi $2,$0,8 la $4,cad addi $5,$0,2 syscall addi $2,$0,10 syscall

#Imprimimos la cadena correspondiente #al numero convertido #Esperamos la pulsacion de una tecla

#Fin del programa

FUNDAMENTOS DE COMPUTADORES Tema 3. Lenguaje Ensamblador

61