Pract Arm
Pract Arm
Pract Arm
Copyright
c 2014 Sergio Barrachina Mir, Maribel Castillo Cata-
ln, Germn Fabregat Llueca, Juan Carlos Fernndez Fernndez,
Germn Len Navarro, Jos Vicente Mart Avils, Rafael Mayo
Gual y Ral Montoliu Cols.
Esta obra se publica bajo la licencia Creative Com-
mons Atribucin-CompartirIgual 4.0 Internacional.
Puede consultar las condiciones de dicha licencia en:
http://creativecommons.org/licenses/by-sa/4.0/.
ndice general
ndice general I
i
ii ndice general
Bibliografa 213
Captulo
1
Primeros pasos con ARM y
Qt ARMSim
ndice
1.1. Introduccin al ensamblador Thumb de ARM . . . 3
1.2. Introduccin al simulador Qt ARMSim . . . . . . . 8
1.3. Literales y constantes en el ensamblador de ARM . 22
1.4. Inicializacin de datos y reserva de espacio . . . . . 25
1.5. Carga y almacenamiento . . . . . . . . . . . . . . . 31
1.6. Problemas del captulo . . . . . . . . . . . . . . . . 41
1
2 Primeros pasos con ARM y Qt ARMSim
Las lneas del programa anterior estn formadas por una instruc-
cin cada una (que indica el nombre de la operacin a realizar y sus
argumentos) y un comentario (que comienza con el carcter @).
Adems, la primera de las lneas declara la etiqueta Bucle, que
podra ser utilizada por otras instrucciones para referirse a dicha lnea.
En el ejemplo, la etiqueta Bucle es utilizada por la instruccin de
salto condicional que hay en la tercera lnea. Cuando se ensamble dicho
programa, el ensamblador traducir la instruccin bne Bucle por la
instruccin mquina bne pc, #-8. Es decir, sustituir, sin entrar en
ms detalles, la etiqueta Bucle por el nmero -8.
introsim-cubos.s -
1 .text
2 main: mov r0, #0 @ Total a 0
3 mov r1, #10 @ Inicializa n a 10
4 loop: mov r2, r1 @ Copia n a r2
5 mul r2, r1 @ Almacena n al cuadrado en r2
6 mul r2, r1 @ Almacena n al cubo en r2
7 add r0, r0, r2 @ Suma [r0] y el cubo de n
8 sub r1, r1, #1 @ Decrementa n en 1
9 bne loop @ Salta a loop si n != 0
10 stop: wfi
11 .end
$ python3 codigo/introsim-cubos.py
El resultado es: 3025
El resultado en hexadecimal es: 0x00000BD1
1.2. Introduccin al simulador Qt ARMSim 15
Recargar la simulacin
Puntos de ruptura
La ejecucin paso a paso permite ver con detenimiento qu es lo que
est ocurriendo en una determinada parte del cdigo. Sin embargo, pue-
de que para llegar a la zona del cdigo que se quiere inspeccionar con
detenimiento haya que ejecutar muchas instrucciones. Por ejemplo, po-
dramos estar interesados en una parte del cdigo al que se llega despus
de completar un bucle con cientos de iteraciones. No tendra sentido te-
ner que ir paso a paso hasta conseguir salir del bucle y llegar a la parte
del cdigo que en realidad queremos ver con ms detenimiento.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1 Dado el siguiente ejemplo de programa ensamblador, identifica
y seala las etiquetas, directivas y comentarios que aparecen en l.
introsim-cubos.s -
1 .text
2 main: mov r0, #0 @ Total a 0
3 mov r1, #10 @ Inicializa n a 10
4 loop: mov r2, r1 @ Copia n a r2
5 mul r2, r1 @ Almacena n al cuadrado en r2
6 mul r2, r1 @ Almacena n al cubo en r2
7 add r0, r0, r2 @ Suma [r0] y el cubo de n
8 sub r1, r1, #1 @ Decrementa n en 1
9 bne loop @ Salta a loop si n != 0
10 stop: wfi
11 .end
r1
r2
r15
......................................................................
22 Primeros pasos con ARM y Qt ARMSim
introsim-numeros.s -
1 .text
2 main: mov r0, #30 @ 30 en decimal
3 mov r1, #0x1E @ 30 en hexadecimal
4 mov r2, #036 @ 30 en octal
5 mov r3, #0b00011110 @ 30 en binario
6 stop: wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Copia el programa anterior en Qt ARMSim, cambia al modo de
simulacin y contesta las siguientes preguntas.
1.4 Cuando el simulador desensambla el cdigo, qu ha pasado con
3
Si has reparado en ello, los prefijos para el hexadecimal, el octal y el binario
comienzan por cero. Pero adems, el prefijo del octal es simplemente un cero; por eso
cuando el nmero est en decimal no puede empezar por cero.
1.3. Literales y constantes en el ensamblador de ARM 23
kcalc
En GNU/Linux se puede utilizar la calculadora kcalc para con-
vertir un nmero entre los distintos sistemas de numeracin.
Para poner la calculadora en el modo de conversin entre sistemas
de numeracin, se debe seleccionar la entrada de men Preferencias
> Modo sistema de numeracin.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Copia el programa anterior en Qt ARMSim, cambia al modo de
simulacin y contesta las siguientes preguntas.
1.6 Cuando el simulador ha desensamblado el cdigo mquina, qu
ha pasado con las letras H, o, l y a? A qu crees que es debido?
1.7 Ejecuta paso a paso el programa, qu nmeros se van almace-
nando en los registros r0 al r3?
......................................................................
Si en lugar de querer especificar un carcter, se quiere especificar una
cadena de caracteres, entonces se debe utilizar el prefijo # y entreco-
millar la cadena entre comillas dobles. Por ejemplo, #"Hola mundo!".
Puesto que la instruccin mov rd, #Offset8 escribe el byte indi-
cado por Offset8 en el registro rd, no tiene sentido utilizar una cadena
de caracteres con dicha instruccin. As que se dejan para ms adelante
los ejemplos de cmo se suelen utilizar los literales de cadenas.
4
En realidad basta con poner una comilla simple delante, #A y #A son
equivalentes.
24 Primeros pasos con ARM y Qt ARMSim
introsim-dias.s -
1 .equ Monday, 1
2 .equ Tuesday, 2
3 @ ...
4
5 .text
6 main: mov r0, #Monday
7 mov r1, #Tuesday
8 @ ...
9 stop: wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.8 Dnde se han declarado las constantes en el cdigo anterior?
Dnde se han utilizado? Dnde se ha utilizado el el carcter # y
dnde no?
1.9 Copia el cdigo anterior en Qt ARMSim, qu ocurre al cambiar
al modo de simulacin? dnde est la declaracin de constantes en el
cdigo mquina? aparecen las constantes Monday y Tuesday en el
cdigo mquina?
5
En lugar de la directiva .equ, se puede utilizar la directiva .set (ambas di-
rectivas son equivalentes). Adems, tambin se pueden utilizar las directivas .equiv
y .eqv, que adems de inicializar una constante, permiten evitar errores de pro-
gramacin, ya que comprueban que la constante no se haya definido previamente (en
otra parte del cdigo que a lo mejor no hemos escrito nosotros, o que escribimos hace
mucho tiempo, lo que viene a ser lo mismo).
1.4. Inicializacin de datos y reserva de espacio 25
introsim-diasreg.s -
1 .equ Monday, 1
2 .equ Tuesday, 2
3 @ ...
4
5 .text
6 day .req r7
7 main: mov day, #Monday
8 mov day, #Tuesday
9 .unreq day
10 @ ...
11 stop: wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.11 Copia el cdigo fuente anterior y ensmblalo, cmo se han
reescrito las instrucciones mov en el cdigo mquina?
......................................................................
datos-palabras2.s -
1 .data @ Comienzo de la zona de datos
2 words: .word 15, 0x15, 015, 0b11
6
Por regla general, cuando hablemos de directivas que inicializan datos, se sobre-
entender que tambin reservan el espacio necesario en memoria para dichos datos;
por no estar repitiendo siempre reserva e inicializacin.
28 Primeros pasos con ARM y Qt ARMSim
3
4 .text
5 stop: wfi
Big-endian y Litle-endian
Cuando se almacena en memoria una palabra y es posible acceder
a posiciones de memoria a nivel de byte, surge la cuestin de en qu
orden se deberan almacenar en memoria los bytes que forman una
palabra.
Por ejemplo, si se quiere almacenar la palabra 0xAABB CCDD en la
posicin de memoria 0x2007 0000, la palabra ocupar los 4 bytes:
0x2007 0000, 0x2007 0001, 0x2007 0002 y 0x2007 0003. Sin embargo,
a qu posiciones de memoria irn cada uno de los bytes de la pala-
bra? Las opciones que se utilizan son:
a) Big-endian b) Little-endian
contenido Value8.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Teclea el siguiente programa en el editor de Qt ARMSim y ensm-
blalo.
datos-byte-palabra.s -
1 .data @ Comienzo de la zona de datos
2 bytes: .byte 0x10, 0x20, 0x30, 0x40
3 word: .word 0x10203040
4
5 .text
6 stop: wfi
.asciz "cadena" 1.24 La directiva .asciz "cadena" tambin sirve para declarar
cadenas. Pero hace algo ms que tienes que averiguar en este ejercicio.
Sustituye en el programa anterior la directiva .ascii por la direc-
tiva .asciz y ensambla de nuevo el cdigo. Hay alguna diferencia en
el contenido de la memoria utilizada? Cul? Describe cul es la funcin
de esta directiva y cul crees que puede ser su utilidad con respecto a
.ascii.
......................................................................
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Dado el siguiente cdigo:
datos-space.s -
1 .data @ Comienzo de la zona de datos
2 byte1: .byte 0x11
3 space: .space 4
4 byte2: .byte 0x22
5 word: .word 0xAABBCCDD
6
7 .text
8 stop: wfi
carga-mov.s -
1 .text
2 main: mov r0, #0x12
3 wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Copia el cdigo anterior y ensmblalo. A continuacin, realiza los
siguientes ejercicios.
1.30 Modifica a mano el contenido del registro r0 para que tenga
el valor 0x12345678 (haz doble clic sobre el contenido del registro).
32 Primeros pasos con ARM y Qt ARMSim
ldr rd, =Inm32 En el caso de tener que cargar un dato que ocupe ms de un by-
te, no se podra utilizar la instruccin mov. Sin embargo, suele ser
habitual tener que cargar datos constantes ms grandes, por lo que el
ensamblador de ARM proporciona una pseudo-instruccin que s que
lo permite: ldr rd, =Inm32. Dicha pseudo-instruccin permite cargar
datos inmediatos de hasta 32 bits.
Por qu ldr rd, =Inm32 no podra ser una instruccin mquina
en lugar de una pseudo-instruccin? Porque puesto que solo el dato in-
mediato ya ocupa 32 bits, no habra bits suficientes para codificar los
otros elementos de la nueva hipottica instruccin mquina. Si recor-
damos lo comentado anteriormente, las instrucciones mquina de ARM
Thumb ocupan generalmente 16 bits (alguna, 32 bits), y puesto que el
operando ya estara ocupando todo el espacio disponible, no sera po-
sible codificar en la instruccin cul es el registro destino, ni destinar
parte de la instruccin a guardar el cdigo de operacin (que adems
de identificar la operacin que se debe realizar, permite al procesador
distinguir a una instruccin de las restantes de su repertorio).
Qu hace el programa ensamblador cuando se encuentra con la
pseudo-instruccin ldr rd, =Inm32? Depende. Si el dato inmediato
ocupa un byte, sustituye la pseudo-instruccin por una instruccin mov
equivalente. Si por el contrario, el dato inmediato ocupa ms de un byte:
i) copia el valor del dato inmediato en la memoria ROM, a continuacin
del cdigo del programa, y ii) sustituye la pseudo-instruccin por una
instruccin de carga relativa al PC.
El siguiente programa muestra un ejemplo en el que se utiliza la
pseudo-instruccin ldr rd, =Inm32. En un primer caso, con un valor
que cabe en un byte. En un segundo caso, con un valor que ocupa una
palabra entera.
carga-ldr-value.s -
1 .text
2 main: ldr r1, =0xFF
3 ldr r2, =0x10203040
4 wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.5. Carga y almacenamiento 33
carga-ldr-label.s -
1 .data
2 word1: .word 0x10203040
3 word2: .word 0x11213141
4 word3: .word 0x12223242
5
6 .text
7 main: ldr r0, =word1
8 ldr r1, =word2
9 ldr r2, =word3
10 wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Copia y ensambla el programa anterior. Luego contesta las siguientes
preguntas.
1.36 En qu direcciones de memoria se encuentran las variables
etiquetadas con word1, word2 y word3?
1.37 Puedes localizar los nmeros que has contestado en la pre-
gunta anterior en la memoria ROM? Dnde?
1.38 El contenido de la memoria ROM tambin se muestra en la
ventana de desensamblado del simulador, puedes localizar ah tambin
dichos nmeros? dnde estn?
34 Primeros pasos con ARM y Qt ARMSim
carga-ldr-rb.s -
1 .data
2 word1: .word 0x10203040
3 word2: .word 0x11213141
4 word3: .word 0x12223242
5
6 .text
7 main: ldr r0, =word1 @ r0 <- 0x20070000
8 mov r1, #8 @ r1 <- 8
9 ldr r2, [r0]
10 ldr r3, [r0,#4]
11 ldr r4, [r0,r1]
12 wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Copia y ensambla el cdigo anterior. A continuacin contesta las
siguientes preguntas.
1.44 La instruccin ldr r2, [r0]:
1.45 Ejecuta el cdigo paso a paso hasta la instruccin ldr r2, [r0]
inclusive y comprueba si es correcto lo que has contestado en el ejercicio
anterior.
1.46 La instruccin ldr r3, [r0,#4]:
Como se puede ver en el cuadro anterior, y al igual que ocurra con las
instrucciones de carga de bytes, las dos primeras variantes que permiten
cargar medias palabras con desplazamiento inmediato, no tienen una
variante equivalente que cargue y, a la vez, extienda el signo de la media
palabra. Una opcin para hacer esto mismo, sin recurrir a la tercera
variante, es la de usar la instruccin de carga sin signo y luego utilizando
la instruccin sxth rd, rm, que extiende el signo de la media palabra
a la palabra.
Hay que tener en cuenta que el desplazamiento, Offset5, debe ser
un nmero mltiplo de 2 comprendido entre 0 y 62.
Ejemplo con ldrh:
carga-ldrh.s -
1 .data
2 half1: .hword -15
3 half2: .hword 20
4 half3: .hword 40
5
6 .text
7 main: ldr r0, =half1 @ r0 <- 0x20070000
8 mov r1, #4 @ r1 <- 4
9 @ Sin extensin de signo
10 ldrh r2, [r0]
11 ldrh r3, [r0,#2]
12 ldrh r4, [r0,r1]
13 @ Con extensin de signo
14 ldrh r5, [r0]
15 sxth r5, r5
16 ldrsh r6, [r0,r1]
17 stop: wfi
carga-str-rb.s -
1 .data
2 word1: .space 4
3 word2: .space 4
4 word3: .space 4
5
6 .text
7 main: ldr r0, =word1 @ r0 <- 0x20070000
8 mov r1, #8 @ r1 <- 8
9 mov r2, #16 @ r2 <- 16
10 str r2, [r0]
11 str r2, [r0,#4]
12 str r2, [r0,r1]
13
14 stop: wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.5. Carga y almacenamiento 39
1.51 Ejecuta el cdigo paso a paso hasta la instruccin str r2, [r0]
inclusive y comprueba si es correcto lo que has contestado en el ejercicio
anterior.
1.52 La instruccin str r2, [r0,#4]:
carga-strb.s -
1 .data
2 byte1: .space 1
3 byte2: .space 1
4 byte3: .space 1
5
6 .text
7 main: ldr r0, =byte1 @ r0 <- 0x20070000
8 mov r1, #2 @ r1 <- 2
9 mov r2, #10 @ r2 <- 10
10 strb r2, [r0]
11 strb r2, [r0,#1]
12 strb r2, [r0,r1]
13 stop: wfi
carga-strh.s -
1 .data
2 hword1: .space 2
3 hword2: .space 2
4 hword3: .space 2
5
6 .text
7 main: ldr r0, =hword1 @ r0 <- 0x20070000
8 mov r1, #4 @ r1 <- 4
9 mov r2, #10 @ r2 <- 10
10 strh r2, [r0]
11 strh r2, [r0,#2]
12 strh r2, [r0,r1]
13 stop: wfi
1.6. Problemas del captulo 41
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.56 Desarrolla un programa ensamblador que reserve espacio para
dos vectores consecutivos, A y B, de 20 palabras.
1.57 Desarrolla un programa ensamblador que realice la siguiente
reserva de espacio en memoria: una palabra, un byte y otra palabra
alineada en una direccin mltiplo de 4.
1.58 Desarrolla un programa ensamblador que realice la siguiente
reserva de espacio e inicializacin de memoria: una palabra con el valor 3,
un byte con el valor 0x10, una reserva de 4 bytes que comience en una
direccin mltiplo de 4, y un byte con el valor 20.
1.59 Desarrolla un programa ensamblador que inicialice, en el espa-
cio de datos, la cadena de caracteres Esto es un problema, utilizando:
a) La directiva .ascii
b) La directiva .byte
c) La directiva .word
ndice
2.1. Operaciones aritmticas . . . . . . . . . . . . . . . . 44
2.2. Operaciones lgicas . . . . . . . . . . . . . . . . . . 50
2.3. Operaciones de desplazamiento . . . . . . . . . . . . 52
2.4. Problemas del captulo . . . . . . . . . . . . . . . . 53
43
44 Instrucciones de procesamiento de datos
oper-add-inm.s -
1 .data @ Zona de datos
2 num: .word 2147483647 @ Mx. positivo representable en Ca2(32)
3 @ (en hexadecimal 0x7fff ffff)
4
5 .text @ Zona de instrucciones
6 main: ldr r0, =num
7 ldr r0, [r0] @ r0 <- [num]
8 add r1, r0, #1 @ r1 <- r0 + 1
9
10 stop: wfi
add (inm) La instruccin add rd, rs, #Inm3 suma dos operandos. Uno de
los operandos est almacenado en un registro, en rs, y el otro en la
propia instruccin, en el campo Inm3; el resultado se almacenar en el
registro rd.
sub (inm) Por su parte, la instruccin sub rd, rs, #Inm3 resta el dato in-
mediato Inm3 del contenido del registro rs y almacena el resultado
en rd.
2.1. Operaciones aritmticas 45
Hay que tener en cuenta que puesto que el campo destinado al dato
inmediato es de solo 3 bits, solo se pueden utilizar estas instrucciones si
el dato inmediato es un nmero entre 0 y 7.
Existe una variante de las instrucciones suma y resta con dato inme-
diato que utilizan el mismo registro como fuente y destino de la opera-
cin: add rd, #Inm8 y sub rd, #Inm8. Estas variantes permiten que
el dato inmediado sea de 8 bits, por lo que se puede indicar un nmero
entre 0 y 255.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Copia el fichero anterior en el simulador, ensmblalo y ejectalo.
2.1 Localiza el resultado de la suma. Cul ha sido? El resultado
obtenido es igual a 2.147.483.647 + 1? (puedes utilizar kcalc, python3 o
modificar a mano el contenido de un registro para comprobarlo).
2.2 Localiza en la parte inferior del simulador el valor de los in-
dicadores (flags). Comprueba que aparece lo siguiente: N z c V, lo que
quiere decir que se han activado los indicadores N y V. Qu significa que
se hayan activado los indicadores N y V? (si dejas el ratn sobre el panel
de los indicadores, se mostrar un pequeo mensaje de ayuda).
2.3 Recarga el simulador, escribe el valor 0x7FFF FFFE en la po-
sicin de memoria 0x2007 0000, y vuelve a ejecutar el cdigo. Se ha
activado algn indicador? Por qu no?
2.4 Vuelve al modo de edicin y sustituye en el programa anterior
la instruccin add r1, r0, #1 por la instruccin add r1, r0, #8,
guarda el fichero y pasa al modo de simulacin. Qu ha ocurrido al
efectuar este cambio? Por qu?
2.5 Vuelve al modo de edicin y modifica el programa original para
que: i) la posicin de memoria etiquetada con num se inicialice con
el nmero 10, y ii) en lugar de la suma con dato inmediato se realice la
siguiente resta con dato inmediato: r1 r0 2. Una vez realizado lo
anterior, guarda el nuevo fichero, vuelve al modo de simulacin y ejecuta
el programa, qu valor hay ahora en r1?
......................................................................
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Copia el programa anterior en el simulador y contesta a las siguientes
preguntas:
2.6 Qu posicin de memoria se ha inicializado con el nmero 10?
Qu posicin de memoria se ha inicializado con el nmero 6?
2.7 Qu hace el cdigo anterior? A qu direccin de memoria
hace la referencia la etiqueta res? Qu resultado se almacena en
la direccin de memoria etiquetada como res cuando se ejecuta el
programa? Es correcto?
2.8 Qu dos instrucciones se han utilizado para almacenar el re-
sultado en la posicin de memoria etiquetada con res?
2.9 Recarga el simulador y ejecuta el programa paso a paso hasta la
instruccin sub r2, r0, r1 inclusive. Se ha activado el indicador Z?
Qu significado tiene dicho indicador?
2.10 Recarga de nuevo el simulador y modifica a mano el contenido
de las posiciones de memoria 0x2007 0000 y 0x2007 0004 para que tengan
el mismo valor, p.e., un 5. Ejecuta de nuevo el programa paso a paso
hasta la instruccin sub r2, r0, r1 inclusive. Se ha activado ahora
el indicador Z? Por qu?
......................................................................
2.1. Operaciones aritmticas 47
oper-cmp.s -
1 .text @ Zona de instrucciones
2 main: mov r0, #10
3 mov r1, #6
4 mov r2, #6
5 cmp r0, r1
6 cmp r1, r0
7 cmp r1, r2
8
9 stop: wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Copia el programa anterior en el simulador y realiza los siguientes
ejercicios.
2.11 Ejecuta paso a paso el programa hasta la instruccin cmp r0, r1
inclusive. Se ha activado el indicador C?
Nota: En el caso de la resta, el indicador C se utiliza para indicar si el
resultado cabe en una palabra (C activo) o, por el contrario, si no cabe
en una palabra (c inactivo), como cuando se dice nos llevamos una
cuando restamos a mano.
2.12 Ejecuta la siguiente instruccin, cmp r1, r0. Qu indica-
dores se han activado? Por qu?
2.13 Ejecuta la ltima instruccin, cmp r1, r2. Qu indicadores
se han activado? Por qu?
......................................................................
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Copia el programa anterior en el simulador, ensmblalo y realiza los
siguientes ejercicios.
2.14 Ejecuta el programa, qu valor se almacena en res1?, y
en res2?
2.15 Completa la siguiente tabla i) recargando el simulador cada
vez; ii) modificando a mano el contenido de la posicin de memoria
etiquetada con num con el valor indicado en la primera columna de
la tabla; y iii) volviendo a ejecutar el programa. Sigue el ejemplo de la
primera lnea.
Valor [num1] [res1] [res2]
10 0x0000 000A 0xFFFF FFF6 0xFFFF FFF5
-10
252645136
2.1. Operaciones aritmticas 49
oper-mul.s -
1 .data @ Zona de datos
2 num1: .word 10
3 num2: .word 6
4 res: .space 4
5
6 .text @ Zona de instrucciones
7 main: ldr r0, =num1
8 ldr r0, [r0] @ r0 <- [num1]
9 ldr r1, =num2
10 ldr r1, [r1] @ r1 <- [num2]
11 mul r1, r0, r1 @ r1 <- [num1] * [num2]
12 ldr r3, =res
13 str r1, [r3] @ [res] <- [num1] * [num2]
14
15 stop: wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.17 Ejecuta el programa anterior y comprueba que en la posicin
de memoria etiquetada con res se ha almacenado el resultado de
10 6.
2.18 Vuelve al modo de edicin y modifica el programa sustituyendo
la instruccin mul r1, r0, r1 por una igual pero en la que el registro
destino no sea ni r0, ni r1. Intenta ensamblar el cdigo, qu ocurre?
2.19 Modifica el programa original sustituyendo mul r1, r0, r1
por una instruccin equivalente que utilice la variante con dos registros
de la multiplicacin. Ejecuta el cdigo y comprueba si el resultado es
correcto.
......................................................................
50 Instrucciones de procesamiento de datos
a b ayb
0 0 0
0 1 0
1 0 0
1 1 1
Como se puede ver, solo cuando los dos bits, a y b, valen 1, el resul-
tado es 1.
Por otro lado, tambin se puede describir el funcionamiento de la
operacin y en funcin del valor de uno de los bits. As, si b vale 0,
a y b ser 0, y si b vale 1, a y b tomar el valor de a. Si expresamos lo
anterior en forma de tabla de verdad, quedara:
b ayb
0 0
1 a
oper-and.s -
1 .data @ Zona de datos
2 num: .word 0x01234567
3 mask: .word 0x00000070
4 res: .space 4
5
6 .text @ Zona de instrucciones
7 main: ldr r0, =num
8 ldr r0, [r0] @ r0 <- [num]
9 ldr r1, =mask
10 ldr r1, [r1] @ r1 <- [mask]
11 and r0, r1 @ r0 <- r0 AND r1
12 ldr r3, =res
13 str r0, [r3] @ [res] <- [num] AND [mask]
14
15 stop: wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.20 Carga el anterior programa en el simulador y ejectalo. Qu
valor, expresado en hexadecimal, se almacena en la posicin de memoria
res? Coincide con el resultado calculado en la explicacin anterior?
2.21 Modifica el cdigo para que sea capaz de almacenar en res el
valor obtenido al conservar tal cual los 16 bits ms significativos del dato
almacenado en num, y poner a cero los 16 bits menos significativos,
salvo el bit cero, que tambin debe conservar su valor original. Qu
valor has puesto en la posicin de memoria etiquetada con mask?
2.22 Desarrolla un programa, basado en los anteriores, que alma-
cene en la posicin de memoria res el valor obtenido al conservar el
valor original de los bits 4, 5 y 6 del nmero almacenado en num y
52 Instrucciones de procesamiento de datos
oper-asr.s -
1 .data @ Zona de datos
2 num: .word 0xffffff41
3 res: .space 4
4
5 .text @ Zona de instrucciones
6 main: ldr r0, =num
7 ldr r0, [r0] @ r0 <- [num]
8 mov r1, #4
9 asr r0, r1 @ r0 <- r0 >> 4
10 ldr r2, =res
11 str r0, [r2]
12
13 stop: wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.23 Copia el programa anterior en el simulador y ejectalo, qu
valor se almacena en la posicin de memoria res? Se ha conservado
el signo del nmero almacenado en num? Modifica el programa pa-
ra comprobar su funcionamiento cuando el nmero que se desplaza es
positivo.
2.24 Modifica el programa propuesto originalmente para que realice
un desplazamiento de 3 bits. Como se puede observar, la palabra original
era 0xFFFF FF41 y al desplazarla se ha obtenido la palabra 0xFFFF FFE8.
Representa ambas palabras en binario y comprueba si la palabra obte-
nida corresponde realmente al resultado de desplazar 0xFFFF FF41 3 bits
a la derecha conservando su signo.
2.4. Problemas del captulo 53
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.29 Desarrolla un programa en ensamblador que defina el vector de
enteros de dos elementos V = [v0 , v1 ] en la memoria de datos y almacene
la suma de sus elementos en la primera direccin de memoria no ocupada
despus del vector.
Para probar el programa, inicializa el vector V con [10, 20].
2.30 Desarrolla un programa en ensamblador que multiplique por
5 los dos nmeros almacenados en las dos primeras posiciones de la me-
moria de datos. Ambos resultados debern almacenarse a continuacin
de forma consecutiva.
Para probar el programa, inicializa las dos primeras palabras de la me-
moria de datos con los nmeros 18 y 1215.
2.31 Desarrolla un programa que modifique el valor de la palabra
almacenada en la primera posicin de la memoria de datos de tal forma
que los bits 11, 7 y 3 se pongan a cero mientras que los bits restantes
conserven el valor original.
54 Instrucciones de procesamiento de datos
ndice
3.1. El registro CCR . . . . . . . . . . . . . . . . . . . . . 56
3.2. Saltos incondicionales y condicionales . . . . . . . . 59
3.3. Estructuras de control condicionales . . . . . . . . . 62
3.4. Estructuras de control repetitivas . . . . . . . . . . 64
3.5. Problemas del captulo . . . . . . . . . . . . . . . . 68
Este captulo forma parte del libro Introduccin a la arquitectura de computadores con
Qt ARMSim y Arduino. Copyright
c 2014 Sergio Barrachina Mir, Maribel Castillo Cataln,
Germn Fabregat Llueca, Juan Carlos Fernndez Fernndez, Germn Len Navarro, Jos
Vicente Mart Avils, Rafael Mayo Gual y Ral Montoliu Cols. Se publica bajo la licencia
Creative Commons Atribucin-CompartirIgual 4.0 Internacional.
55
56 Instrucciones de control de flujo
cap3-E0.s -
1 .text
2 main: mov r1, #10
3 mov r2, #5
4 mov r3, #10
5 cmp r1, r2
6 cmp r1, r3
7 cmp r2, r3
8 stop: wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Copia y ensambla el programa anterior. A continuacin, ejecuta el
programa paso a paso conforme vayas respondiendo las siguientes pre-
guntas:
3.1 Carga y ejecuta el programa anterior. Se activa el indicador N
tras la ejecucin de la instruccin cmp r1, r2? y el indicador Z?
cap3-E1.s -
1 .text
2 main: mov r0, #5
3 mov r1, #10
4 mov r2, #100
5 mov r3, #0
6 b salto
7 add r3, r1, r0
8 salto: add r3, r3, r2
9 stop: wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4 Carga y ejecuta el programa anterior. Qu valor almacena el
registro r3 al finalizar el programa?
cap3-E2.s -
1 .text
2 main: mov r0, #5
3 mov r1, #10
4 mov r2, #5
5 mov r3, #0
3.2. Saltos incondicionales y condicionales 61
6 cmp r0, r2
7 beq salto
8 add r3, r0, r1
9 salto: add r3, r3, r1
10 stop: wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.8 Carga y ejecuta el programa anterior. Qu valor tiene el registro
r3 cuando finaliza el programa?
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.18 Carga y ejecuta el programa anterior. Qu valor tiene la
posicin de memoria Z cuando finaliza el programa?
3.3. Estructuras de control condicionales 63
cap3-E4.s -
1 .data
2 X: .word 1
3 Y: .word 1
4 Z: .word 0
5
6 .text
7 main: ldr r0, =X
8 ldr r0, [r0] @ r0 <- [X]
9 ldr r1, =Y
10 ldr r1, [r1] @ r1 <- [Y]
64 Instrucciones de control de flujo
11
12 cmp r0, r1
13 bne else
14 add r2, r0, r1 @ r2 <- [X] + [Y]
15 b finsi
16
17 else: add r2, r0, #5 @ r2 <- [X] + 5
18
19 finsi: ldr r3, =Z
20 str r2, [r3] @ [Z] <- r2
21
22 stop: wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.21 Carga y ejecuta el programa anterior. Qu valor hay en la
posicin de memoria Z cuando finaliza el programa?
3.22 Cambia el valor de Y para que sea distinto de X y vuelve a
ejecutar el programa. Qu valor hay ahora la posicin de memoria Z al
finalizar el programa?
3.23 Supn que el programa anterior en Python3, en lugar de la l-
nea if X == Y:, tuviera la lnea if X > Y:. Cambia el programa en
ensamblador para se tenga en cuenta dicho cambio. Qu modificaciones
has realizado en el programa en ensamblador?
3.24 Supn que el programa anterior en Python3, en lugar de la
lnea if X == Y:, tuviera la lnea if X <= Y:. Cambia el programa
en ensamblador para se tenga en cuenta dicho cambio. Qu modifica-
ciones has realizado en el programa en ensamblador?
......................................................................
cap3-E6.s -
1 .data
2 X: .word 1
3 E: .word 1
4 LIM: .word 100
5
6 .text
7 main: ldr r0, =X
8 ldr r0, [r0] @ r0 <- X
9 ldr r1, =E
10 ldr r1, [r1] @ r1 <- E
11 ldr r2, =LIM
12 ldr r2, [r2] @ r2 <- LIM
13
14 bucle: cmp r0, r2
15 bpl finbuc
16 lsl r3, r1, #1 @ r3 <- 2 * [E]
17 add r0, r0, r3 @ r0 <- [X] + 2 * [E]
18 add r1, r1, #1 @ r1 <- [E] + 1
19 ldr r4, =X
20 str r0, [r4] @ [X] <- r0
21 ldr r4, =E
22 str r1, [r4] @ [E] <- r1
23 b bucle
24
25 finbuc: wfi
66 Instrucciones de control de flujo
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.25 Qu hacen las instrucciones cmp r0, r2, bpl finbuc y
b bucle?
3.26 Por qu se ha usado bpl y no bmi?
3.27 Qu indicador del registro CCR se est comprobando cuando se
ejecuta la instruccin bpl? Cmo debe estar dicho indicador, activado
o desactivado, para que se ejecute el interior del bucle?
3.28 Qu instruccin se ha utilizado para calcular 2E? Qu hace
dicha instruccin?
3.29 En el cdigo mostrado se actualiza el contenido de las va-
riables X y E en cada iteracin del bucle. Se te ocurre algn tipo de
optimizacin que haga que dicho bucle se ejecute mucho ms rpido?
(El resultado final del programa debe ser el mismo.)
......................................................................
cap3-E5.s -
1 .data
2 V: .word 2, 4, 6, 8, 10
3 n: .word 5
4 suma: .word 0
5
6 .text
7 main: ldr r0, =V @ r0 <- direccin de V
8 ldr r1, =n
9 ldr r1, [r1] @ r1 <- n
10 ldr r2, =suma
11 ldr r2, [r2] @ r2 <- suma
12 mov r3, #0 @ r3 <- 0
13
14 bucle: cmp r3, r1
15 beq finbuc
16 ldr r4, [r0]
17 add r2, r2, r4 @ r2 <- r2 + V[i]
18 add r0, r0, #4
19 add r3, r3, #1
20 b bucle
21
22 finbuc: ldr r0, =suma
23 str r2, [r0] @ [suma] <- r2
24
25 stop: wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.35 Implementa un programa que dados dos nmeros almacenados
en dos posiciones de memoria A y B, almacene el valor absoluto de la
resta de ambos en la posicin de memoria RES. Es decir, si A es mayor
que B deber realizar la operacin A B y almacenar el resultado en
RES, y si B es mayor que A, entonces deber almacenar B A.
3.36 Implementa un programa que dado un vector, calcule el n-
mero de elementos de un vector que son menores a un nmero dado. Por
ejemplo, si el vector es [2, 4, 6, 3, 10, 12, 2] y el nmero es 5, el resultado
esperado ser 4, puesto que hay 4 elementos del vector menores a 5.
3.37 Implementa un programa que dada las notas de 2 exmenes
parciales almacenadas en memoria (con notas entre 0 y 10), calcule la
nota final (sumando las dos notas) y almacene en memoria la cadena
de caracteres APROBADO si la nota final es mayor o igual a 10 y
SUSPENDIDO si la nota final es inferior a 10.
3.38 Modifica el programa anterior para que almacene en memoria
la cadena de caracteres APROBADO si la nota final es mayor o igual a
10 pero menor a 14, NOTABLE si la nota final es mayor o igual a 14
pero menor a 18 y SOBRESALIENTE si la nota final es igual o superior
a 18.
3.39 Modifica el programa anterior para que si alguna de las notas
de los exmenes parciales es inferior a 5, entonces se almacene NOSU-
PERA independientemente del valor del resto de exmenes parciales.
3.40 Implementa un programa que dado un vector, sume todos los
elementos del mismo mayores a un valor dado. Por ejemplo, si el vector
es [2, 4, 6, 3, 10, 1, 4] y el valor 5, el resultado esperado ser 6 + 10 = 16
3.41 Implementa un programa que dado un vector, sume todos los
elementos pares. Por ejemplo, si el vector es [2, 7, 6, 3, 10], el resultado
esperado ser 2 + 6 + 10 = 18.
3.42 Implementa un programa que calcule los N primeros nmeros
de la sucesin de Fibonacci. La sucesin comienza con los nmeros 1
y 1 y a partir de estos, cada trmino es la suma de los dos anteriores.
Es decir que el tercer elemento de la sucesin es 1 + 1 = 2, el cuarto
1 + 2 = 3, el quinto 2 + 3 = 5 y as sucesivamente. Por ejemplo, los
3.5. Problemas del captulo 69
N = 10 primeros son [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]. Para ello debers usar
una estructura de repeticin adecuada y almacenar los valores obtenidos
en memoria.
3.43 Modifica el programa anterior para que calcule elementos de la
sucesin de Fibonacci hasta que el ltimo elemento calculado sea mayor
a un valor concreto.
......................................................................
Captulo
4
Modos de direccionamiento y
formatos de instruccin
ndice
4.1. Direccionamiento directo a registro . . . . . . . . . 74
4.2. Direccionamiento inmediato . . . . . . . . . . . . . 75
4.3. Direccionamiento relativo a registro con desplaza-
miento . . . . . . . . . . . . . . . . . . . . . . . . . 77
4.4. Direccionamiento relativo a registro con registro de
desplazamiento . . . . . . . . . . . . . . . . . . . . . 82
4.5. Direccionamiento en las instrucciones de salto in-
condicional y condicional . . . . . . . . . . . . . . . 85
4.6. Ejercicios del captulo . . . . . . . . . . . . . . . . . 88
Este captulo forma parte del libro Introduccin a la arquitectura de computadores con
Qt ARMSim y Arduino. Copyright
c 2014 Sergio Barrachina Mir, Maribel Castillo Cataln,
Germn Fabregat Llueca, Juan Carlos Fernndez Fernndez, Germn Len Navarro, Jos
Vicente Mart Avils, Rafael Mayo Gual y Ral Montoliu Cols. Se publica bajo la licencia
Creative Commons Atribucin-CompartirIgual 4.0 Internacional.
71
72 Modos de direccionamiento y formatos de instruccin
......................................................................
mod-dir-b.s -
4
Si el bit 0 no se considerara como un bit implcito a la instruccin, el rango
del desplazamiento correspondera al rango del complemento a 2 con 11 bits para
nmeros pares, es decir, [1024, 1022] bytes con respecto al PC.
4.5. Direccionamiento en las instrucciones de salto incondicional y condicional 87
1 .text
2 main: b salto
3 b salto
4 b salto
5 b salto
6 salto: mov r0, r0
7 mov r1, r1
8 b salto
9 b salto
10
11 stop: wfi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Copia el programa anterior y ensmblalo. No lo ejecutes (el programa
no tiene ningn sentido y si se ejecutara entrara en un bucle sin fin, su
nico propsito es mostrar qu desplazamiento se almacena en cada
caso).
4.21 Cul es la direccin memoria de la instruccin etiquetada con
salto?
4.22 Segn la explicacin anterior, cuando se va a realizar el salto
desde la primera instruccin, qu valor tendr el registro PC?, qu
nmero se ha puesto como desplazamiento?, cunto suman?
4.23 Cunto vale el campo Ofsset11 de la primera instruccin?
Qu relacin hay entre el desplazamiento y el valor codificado de dicho
desplazamiento?
4.24 Observa con detenimiento las dems instrucciones, qu nme-
ros se han puesto como desplazamiento en cada uno de ellas? Comprueba
que al sumar dicho desplazamiento al PC+4 se consigue la direccin de
la instruccin a la que se quiere saltar.
......................................................................
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.25 Supn un vector, V , de 26 palabras y dos variables x e y
asignadas a los registros r0 y r1. Asume que la direccin base del vector
V se encuentra en el registro r2. Escribe el cdigo ensamblador que
implementara la siguiente operacin: x = V [25] + y.
4.26 Supn un vector, V , de 26 palabras y una variable y asignada
al registro r1. Asume que la direccin base del vector V se encuentra
en el registro r2. Escribe el cdigo ensamblador que implementara la
siguiente operacin: V [10] = V [25] + y.
4.27 Escribe un cdigo en ensamblador que dado un vector, V ,
de n bytes, almacene en el registro r1 la posicin del primer elemento
de dicho vector que es un 1. Debes realizar este ejercicio sin utilizar el
direccionamiento relativo a registro con registro de desplazamiento.
Comprueba el funcionamiento del programa inicializando el vector
V a [0, 0, 1, 0, 1, 0, 1, 0, 0, 0] y, por tanto, n a 10.
4.28 Escribe un cdigo en ensamblador que dado un vector, V ,
de n bytes, almacene en el registro r1 la posicin del ltimo elemento
de dicho vector que es un 1. Debes realizar este ejercicio sin utilizar el
direccionamiento relativo a registro con registro de desplazamiento.
Comprueba el funcionamiento del programa inicializando el vector
V a [0, 0, 1, 0, 1, 0, 1, 0, 0, 0] y, por tanto, n a 10.
4.29 Escribe una nueva versin del programa del ejercicio 4.27, pero
esta vez utilizando el direccionamiento relativo a registro con registro
de desplazamiento.
4.30 Escribe una nueva versin del programa del ejercicio 4.28, pero
esta vez utilizando el direccionamiento relativo a registro con registro
de desplazamiento.
4.31 Escribe un cdigo ensamblador cuya primera instruccin sea
ldr r2, [r5, #124]; el resto del cdigo deber obtener a partir de la
4.6. Ejercicios del captulo 89
ndice
5.1. Llamada y retorno de una subrutina . . . . . . . . . 94
5.2. Paso de parmetros . . . . . . . . . . . . . . . . . . 97
5.3. Problemas del captulo . . . . . . . . . . . . . . . . 103
Este captulo forma parte del libro Introduccin a la arquitectura de computadores con
Qt ARMSim y Arduino. Copyright
c 2014 Sergio Barrachina Mir, Maribel Castillo Cataln,
Germn Fabregat Llueca, Juan Carlos Fernndez Fernndez, Germn Len Navarro, Jos
Vicente Mart Avils, Rafael Mayo Gual y Ral Montoliu Cols. Se publica bajo la licencia
Creative Commons Atribucin-CompartirIgual 4.0 Internacional.
91
92 Introduccin a la gestin de subrutinas
1
La palabra inglesa library se suele traducir errneamente en castellano como
librera; la traduccin correcta es biblioteca.
94 Introduccin a la gestin de subrutinas
Desde el punto de vista que nos ocupa, el de los mecanismos que pro-
porciona un procesador para soportar determinadas tareas de progra-
macin, el uso de subrutinas implica que se deben facilitar las siguientes
acciones: llamar una subrutina; pasar los parmetros con los que debe
operar la subrutina; devolver los resultados; y continuar la ejecucin del
programa a partir de la siguiente instruccin en cdigo mquina a la
que invoc a la subrutina. Es por ello que en este captulo se presentan
los aspectos ms bsicos relacionados con la gestin de subrutinas en el
ensamblador Thumb de ARM. Es decir, cmo llamar y retornar de una
subrutina y cmo intercambiar informacin entre el programa invocador
y la subrutina utilizando registros.
Para complementar la informacin mostrada en este captulo y ob-
tener otro punto de vista sobre este tema, se puede consultar el Aparta-
do 3.8 Subroutine Call and Return del libro Computer Organization
and Architecture: Themes and Variations de Alan Clements. Conviene
tener en cuenta que en dicho apartado se utiliza el juego de instruccio-
nes ARM de 32 bits y la sintaxis del compilador de ARM, mientras que
en este libro se describe el juego de instrucciones Thumb de ARM y la
sintaxis del compilador GCC.
bl subr
...
introsub-suma-valor.s -
1 .data
2 datos: .word 5, 8, 3, 4
3 suma1: .space 4
4 suma2: .space 4
5 .text
6
7 @ Programa invocador
8
9 main: ldr r4, =datos
96 Introduccin a la gestin de subrutinas
10
11 ldr r0, [r4]
12 ldr r1, [r4, #4]
13 primera: bl suma
14 ldr r5, =suma1
15 str r2, [r5]
16
17 ldr r0, [r4, #8]
18 ldr r1, [r4, #12]
19 segunda: bl suma
20 ldr r5, =suma2
21 str r2, [r5]
22
23 stop: wfi
24
25 @ Subrutina
26
27 suma: add r2, r1, r0
28 mov pc, lr
29
30 .end
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.1 Cul es el contenido del PC y del registro lr antes y despus
de ejecutar la instruccin bl suma etiquetada como primera?
Programa invocador
introsub-suma-valor.s -
1 .data
2 datos: .word 5, 8, 3, 4
3 suma1: .space 4
4 suma2: .space 4
5 .text
5.2. Paso de parmetros 99
6
7 @ Programa invocador
8
9 main: ldr r4, =datos
10
11 ldr r0, [r4]
12 ldr r1, [r4, #4]
13 primera: bl suma
14 ldr r5, =suma1
15 str r2, [r5]
16
17 ldr r0, [r4, #8]
18 ldr r1, [r4, #12]
19 segunda: bl suma
20 ldr r5, =suma2
21 str r2, [r5]
22
23 stop: wfi
24
25 @ Subrutina
26
27 suma: add r2, r1, r0
28 mov pc, lr
29
30 .end
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.7 Enumera los registros que se han utilizado para pasar los par-
metros a la subrutina.
5.8 Los anteriores registros se han utilizado para pasar parmetros
de entrada o de salida?
5.9 Anota qu registro se ha utilizado para devolver el resultado al
programa invocador.
5.10 El anterior registro se ha utilizado para pasar un parmetro
de entrada o de salida?
5.11 Seala qu instrucciones se corresponden a cada uno de las
acciones enumeradas en la Figura 5.2. (Hazlo nicamente para la primera
de las dos llamadas.)
......................................................................
Programa invocador
6. Retornar
introsub-suma-referencia.s -
1 .data
2 datos: .word 5, 8, 3, 4
3 suma1: .space 4
4 suma2: .space 4
5 .text
6
7 @ Programa invocador
8
9 main: ldr r0, =datos
10 ldr r1, =datos + 4
11 ldr r2, =suma1
12 primera: bl suma
13
14 ldr r0, =datos + 8
15 ldr r1, =datos + 12
16 ldr r2, =suma2
17 segunda: bl suma
18
5.2. Paso de parmetros 101
19 stop: wfi
20
21 @ Subrutina
22
23 suma: ldr r4, [r0]
24 ldr r5, [r1]
25 add r6, r4, r5
26 str r6, [r2]
27 mov pc, lr
28
29 .end
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.12 Enumera los registros que se han utilizado para pasar la di-
reccin de los parmetros de entrada a la subrutina.
5.13 Anota qu registro se ha utilizado para pasar la direccin del
parmetro de salida a la subrutina.
5.14 Seala qu instrucciones se corresponden con cada una de
las acciones enumeradas en la Figura 5.3. (Hazlo nicamente para la
primera de las dos llamadas.)
......................................................................
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.15 Antes de desarrollar el cdigo de la subrutina, contesta las
siguientes preguntas:
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.19 Realiza el siguiente ejercicio:
ndice
6.1. La pila . . . . . . . . . . . . . . . . . . . . . . . . . 106
6.2. Bloque de activacin de una subrutina . . . . . . . 111
6.3. Problemas del captulo . . . . . . . . . . . . . . . . 122
Este captulo forma parte del libro Introduccin a la arquitectura de computadores con
Qt ARMSim y Arduino. Copyright
c 2014 Sergio Barrachina Mir, Maribel Castillo Cataln,
Germn Fabregat Llueca, Juan Carlos Fernndez Fernndez, Germn Len Navarro, Jos
Vicente Mart Avils, Rafael Mayo Gual y Ral Montoliu Cols. Se publica bajo la licencia
Creative Commons Atribucin-CompartirIgual 4.0 Internacional.
105
106 Gestin de subrutinas
6.1. La pila
Una pila o cola LIFO (Last In First Out) es una estructura de datos
que permite aadir y extraer datos con la peculiaridad de que los datos
introducidos solo se pueden extraer en el sentido contrario al que fueron
introducidos. Aadir datos en una pila recibe el nombre de apilar (push,
en ingls) y extraer datos de una pila, desapilar (pop, en ingls).
Una analoga que se suele emplear para describir una pila es la de un
montn de libros puestos uno sobre otro. Sin embargo, para que dicha
analoga sea correcta, es necesario limitar la forma en la que se pueden
aadir o quitar libros de dicho montn. Cuando se quiera aadir un
libro, ste deber colocarse encima de los que ya hay (lo que implica
que no es posible insertar un libro entre los que ya estn en el montn).
6.1. La pila 107
Por otro lado, cuando se quiera quitar un libro, solo se podr quitar el
libro que est ms arriba en el montn (por tanto, no se puede quitar
un libro en particular si previamente no se han quitado todos los que
estn encima de l). Teniendo en cuenta dichas restricciones, el montn
de libros acta como una pila, ya que solo se pueden colocar nuevos
libros sobre los que ya estn en el montn y el ltimo libro colocado en
la pila de libros ser el primero en ser sacado de ella.
Un computador no dispone de un dispositivo especfico que imple-
mente una pila en la que se puedan introducir y extraer datos. La pila en
un computador se implementa utilizando los siguientes elementos: me-
moria y un registro. La memoria se utiliza para almacenar los elementos
que se vayan introduciendo en la pila y el registro para apuntar a la
direccin del ltimo elemento introducido en la pila (lo que se conoce
como el tope de la pila).
Puesto que la pila se almacena en memoria, es necesario definir el
sentido de crecimiento de la pila con respecto a las direcciones de me-
moria utilizadas para almacenar la pila. La arquitectura ARM sigue el
convenio ms habitual: la pila crece de direcciones de memoria altas a
direcciones de memoria bajas. Es decir, cuando se apilen nuevos datos,
stos se almacenarn en direcciones de memoria ms bajas que los que
se hubieran apilado previamente. Por tanto, al aadir elementos, la di-
reccin de memoria del tope de la pila disminuir; y al quitar elementos,
la direccin de memoria del tope de la pila aumentar.
Como ya se ha comentado, la direccin de memoria del tope de la
pila se guarda en un registro. Dicho registro recibe el nombre de puntero
de pila o sp (de las siglas en ingls de stack pointer). La arquitectura
ARM utiliza como puntero de pila el registro r13.
Como se puede intuir a partir de lo anterior, introducir y extraer da-
tos de la pila requerir actualizar el puntero de pila y escribir o leer de la
memoria con un cierto orden. Afortunadamente, la arquitectura ARM
proporciona dos instrucciones que se encargan de realizar todas las ta-
reas asociadas al apilado y al desapilado: push y pop, respectiva-
mente, que se explican en el siguiente apartado.
Sin embargo, y aunque para un uso bsico de la pila es suficiente con
utilizar las instrucciones push y pop, para utilizar la pila de una for-
ma ms avanzada, como se ver ms adelante, es necesario comprender
en qu consisten realmente las acciones de apilado y desapilado.
La operacin de apilar se realiza en dos pasos. En el primero de ellos
se decrementa el puntero de pila en tantas posiciones como el tamao
en bytes alineado a 4 de los datos que se desean apilar. En el segundo,
se almacenan los datos que se quieren apilar a partir de la direccin
indicada por el puntero de pila. As por ejemplo, si se quisiera apilar la
palabra que contiene el registro r4, los pasos que se debern realizar son:
i) decrementar el puntero de pila en 4 posiciones, sub sp, sp, #4, y
108 Gestin de subrutinas
Direcciones
superiores
(a) (b)
Direcciones
superiores
(a) (b)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Realiza los siguientes ejercicios relacionados con la operacin apilar.
6.1 Suponiendo que el puntero de pila contiene el valor 0x7fff effc
y que se desea apilar una palabra (4 bytes). Qu valor deber pasar a
6.1. La pila 109
subrutina-apilar-r4r5.s -
1 .text
2 main:
3 mov r4, #10 @ r4<-10
4 mov r5, #13 @ r5<-13
5 sub sp, sp, #4 @ Actualiza sp (sp<-sp-4)
6 str r4, [sp] @ Apila r4
7 sub sp, sp, #4 @ Actualiza sp (sp<-sp-4)
8 str r5, [sp] @ Apila r5
9
10 stop: wfi
11 .end
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Copia el programa anterior, cambia al modo de simulacin y realiza
los siguientes ejercicios:
6.4 Ejecuta el programa paso a paso y comprueba en qu posicio-
nes de memoria, pertenecientes al segmento de pila, se almacenan los
contenidos de los registros r4 y r5.
6.5 Modifica el programa anterior para que en lugar de actualizar el
puntero de pila cada vez que se pretende apilar un registro, se realice una
nica actualizacin del puntero de pila al principio y, a continuacin, se
almacenen los registros r4 y r5. Los registros deben quedar apilados en
el mismo orden que en el programa original.
......................................................................
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Realiza los siguientes ejercicios relacionados con la operacin desapi-
lar.
6.6 Qu instruccin se utilizar para desapilar el dato contenido
en el tope de la pila y cargarlo en el registro r5?
6.7 Qu instruccin en ensamblador ARM se utilizar para actua-
lizar el puntero de pila?
110 Gestin de subrutinas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Copia el programa anterior en el simulador y contesta a las siguientes
preguntas mientras realizas una ejecucin paso a paso.
6.10 Cul es el contenido del puntero de pila antes y despus de
la ejecucin de la instruccin push?
6.11 En qu posiciones de memoria, pertenecientes al segmento
de pila, se almacenan los contenidos de los registros r4 y r5?
6.12 Qu valores tienen los registros r4 y r5 una vez realizadas las
operaciones de suma y resta?
6.13 Qu valores tienen los registros r4 y r5 tras la ejecucin de
la instruccin pop?
6.2. Bloque de activacin de una subrutina 111
subrutina-llamada-arm-v2.s -
1 .data
2 datos: .word 5, 8, 3, 4
3 suma1: .space 4
4 suma2: .space 4
5 .text
6
7 main: ldr r0, =datos @ Paso de parametros para sumatorios
8 ldr r1, =suma1
9 salto1: bl sumatorios @ Llama a la subrutina sumatorios
10 stop: wfi @ Finaliza la ejecucion
11
12 sumatorios: mov r7, #2
13 mov r5, r0
14 mov r6, r1
15 for: cmp r7, #0
16 beq salto4
17 ldr r0, [r5] @ Paso de parametros para suma_elem
18 ldr r1, [r5, #4]
19 salto2: bl suma_elem @ Llama a la subrutina suma_elem
20 str r2, [r6]
21 add r5, r5, #8
22 add r6, r6, #4
23 sub r7, r7, #1
24 b for
25 salto4: mov pc, lr
26
27 suma_elem: add r2, r1, r0
28 salto3: mov pc, lr
29
30 .end
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Edita el programa anterior, crgalo en el simulador y ejectalo paso
6.2. Bloque de activacin de una subrutina 113
a paso.
6.16 Dnde pasa el control del programa tras la ejecucin de la
instruccin etiquetada por salto1? Qu valor se carga en el registro
lr despus de ejecutar la instruccin etiquetada por salto1?
Registro lr Registro lr
r_S2 r_S2
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.21 Modifica el fragmento de cdigo anterior para que la direccin
de retorno se apile y desapile de forma adecuada.
......................................................................
6.2. Bloque de activacin de una subrutina 115
sp r_S1
sp r_main r_main
sp
Direcciones
inferiores
sp
Variables
locales
Registros
salvados
Parmetro 5
Parmetro 6
Direcciones
superiores
Direcciones
inferiores
sp
Variables
locales
Invocado
Bloque de
activacin
Registros
salvados
Parmetro 5
Invocador
Parmetro 6
Direcciones
superiores
subrutina-varlocal-v0.s -
1 .data
2 A: .word 7, 6, 5, 4, 3, 2
3 dim: .word 6
4 .text
5
6 @ Programa invocador
7 main: ldr r0, =A
8 ldr r4, =dim
120 Gestin de subrutinas
57
58 @ subrutina sumatorio
59 sumatorio: push {r5, r6, r7, lr}
60 mov r2, #0
61 mov r6, r1
62 mov r5, r0
63 for3: cmp r6, #0
64 beq finfor3
65 ldr r7, [r5]
66 add r5, r5, #4
67 add r2, r2, r7
68 sub r6, r6, #1
69 b for3
70 finfor3: pop {r5, r6, r7, pc}
71
72 .end
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Carga el programa anterior en el simulador y contesta a las siguientes
preguntas:
6.22 Localiza el fragmento de cdigo del programa ensamblador
donde se pasan los parmetros a la subrutina sumatorios. Indica cun-
tos parmetros se pasan, el lugar por donde se pasan y el tipo de par-
metros.
6.23 Indica el contenido del registro lr una vez ejecutada la ins-
truccin bl sumatorios.
6.24 Dibuja y detalla (con los desplazamientos correspondientes)
el bloque de activacin creado por la subrutina sumatorios. Justifica
el almacenamiento de cada uno de los datos que contiene el bloque de
activacin.
6.25 Indica el fragmento de cdigo del programa ensamblador don-
de se pasan los parmetros a la subrutina sumatorio. Indica cuntos
parmetros se pasan, el lugar por donde se pasan y el tipo de parmetros.
6.26 Indica el contenido del registro lr una vez ejecutada la ins-
truccin bl sumatorio.
6.27 Dibuja el bloque de activacin de la subrutina sumatorio.
6.28 Una vez ejecutada la instruccin pop {r5, r6, r7, pc} de la
subrutina sumatorio Dnde se recupera el valor que permite retornar
a la subrutina sumatorios?
6.29 Localiza el fragmento de cdigo donde se desapila el bloque
de activacin de la subrutina sumatorios.
122 Gestin de subrutinas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.31 Desarrolla dos subrutinas en ensamblador: subr1 y subr2.
La subrutina subr1 tomar como entrada una matriz de enteros de
dimensin m n y devolver dicha matriz pero con los elementos de
cada una de sus filas invertidos. Para realizar la inversin de cada una
de las filas se deber utilizar la subrutina subr2. Es decir, la subrutina
subr2 deber tomar como entrada un vector de enteros y devolver
dicho vector con sus elementos invertidos.
(Pista: Si se apilan elementos en la pila y luego se desapilan, se
obtienen los mismos elementos pero en el orden inverso.)
6.32 Desarrolla tres subrutinas en ensamblador, subr1, subr2
y subr3. La subrutina subr1 devolver un 1 si las dos cadenas de
caracteres que se le pasan como parmetro contienen el mismo nmero
de los distintos caracteres que las componen. Es decir, devolver un 1 si
una cadena es un anagrama de la otra. Por ejemplo, la cadena ramo
es un anagrama de mora.
La subrutina subr1 utilizar las subrutinas subr2 y subr3. La
subrutina subr2 deber calcular cuntos caracteres de cada tipo tiene
la cadena que se le pasa como parmetro. Por otra lado, la subrutina
subr3 devolver un 1 si el contenido de los dos vectores que se le pasa
como parmetros son iguales.
Suponer que las cadenas estn compuestas por el conjunto de letras
que componen el abecedario en minsculas.
6.33 Desarrolla en ensamblador la siguiente subrutina recursiva
descrita en lenguaje Python3:
1 def ncsr(n, k):
2 if k > n:
3 return 0
4 elif n == k or k == 0:
5 return 1
6 else:
7 return ncsr(n-1, k) + ncsr(n-1, k-1)
ndice
7.1. Generalidades y problemtica de la entrada/salida . 126
7.2. Estructura de los sistemas y dispositivos de entra-
da/salida . . . . . . . . . . . . . . . . . . . . . . . . 129
7.3. Gestin de la entrada/salida . . . . . . . . . . . . . 133
7.4. Transferencia de datos y DMA . . . . . . . . . . . . 141
Este captulo forma parte del libro Introduccin a la arquitectura de computadores con
Qt ARMSim y Arduino. Copyright
c 2014 Sergio Barrachina Mir, Maribel Castillo Cataln,
Germn Fabregat Llueca, Juan Carlos Fernndez Fernndez, Germn Len Navarro, Jos
Vicente Mart Avils, Rafael Mayo Gual y Ral Montoliu Cols. Se publica bajo la licencia
Creative Commons Atribucin-CompartirIgual 4.0 Internacional.
125
126 Entrada/Salida: introduccin
registro lgico -es decir, un nico registro desde el punto de vista del
procesador- e incluso que un bit tenga doble uso, de control y esta-
do, segn el momento. Un ejemplo comn en los conversores analgico-
digitales es disponer de un bit de control que escribe el procesador para
iniciar la conversin -ponindolo a 1, por ejemplo- y que el dispositi-
vo cambia de valor -a 0 en este ejemplo- cuando ha terminado -tpica
informacin de estado- y el resultado est disponible en un registro de
datos.
Como se ha visto, cuando el procesador quiere realizar una deter-
minada operacin de entrada/salida debe leer o escribir en los registros
del controlador. Por lo tanto, estos registros deben ser accesibles por el
procesador a travs de su conjunto de instrucciones. Este acceso puede
realizarse de dos formas:
ej-consulta-estado.s -
1 ldr r7, =ST_IMPR @ Direccin del registro de estado
2 ldr r6, =0x00000340 @ Mscara para diversos bits
3 ldr r0, [r7] @ Leemos el puerto
4 ands r0, r6 @ y verificamos los bits
5 beq sigue @ Seguimos si no hay avisos
6 bl TRAT_IMPR @ Llamamos a la subrutina
7 sigue:
8 ... @ Continuamos sin prestar atencin
ndice
8.1. Entrada/salida de propsito general (GPIO - Ge-
neral Purpose Input Output) . . . . . . . . . . . . . 145
8.2. Gestin del tiempo . . . . . . . . . . . . . . . . . . 163
8.3. Gestin de excepciones e interrupciones en el AT-
SAM3X8E . . . . . . . . . . . . . . . . . . . . . . . 183
8.4. El controlador de DMA del ATSAM3X8E . . . . . . 190
145
146 Entrada/Salida: dispositivos
ej-entrada-salida.s -
1 ldr r0, [r7, #PULSADOR] @ Leemos el nivel
2 cmp r0, #1 @ Si no est pulsado
3 bne sigue @ seguimos
4 mov r0, #1 @ Escribimos 1 para
5 str r0, [r7, #LED] @ encender el LED
ej-acceso-es.s -
1 ldr r7, =PB @ Direccin del puerto
2 ldr r6, =0x00100000 @ Mscara para el bit 20
3 ldr r0, [r7] @ Leemos el puerto
4 ands r0, r6 @ y verificamos el bit
5 beq sigue @ Seguimos si est a 0
6 ldr r6, =0x00001000 @ Mscara para el bit 12
7 ldr r0, [r7] @ Leemos el puerto
8 orr r0, r6 @ ponemos a 1 el bit
9 str r0, [r7] @ y lo escribimos en el puerto
como salida. Dado que las entradas son elctricamente ms seguras, los
pines suelen estar configurados como tales tras el reset del sistema. As,
el procedimiento normal para inicializar un pin de salida es escribir su
valor mientras est configurado como entrada, y luego configurarlo como
salida. Esto permite adems fijar valores lgicos en el exterior mediante
resistencias, que si son de valor elevado permitirn posteriormente el
funcionamiento normal del pin como salida.
Para comprender adecuadamente esta ltima afirmacin, vamos a
estudiar brevemente las caractersticas elctricas de los pines de entra-
da/salida. Como hemos dicho, la forma de interactuar con el exterior de
un pin de E/S es tpicamente mediante una tensin elctrica presente en
l. En el caso de las salidas, cuando escribimos un 1 lgico en el regis-
tro se tendr un cierto voltaje en el pin correspondiente, y otro distinto
cuando escribimos un 0. En el de las entradas, al leer el pin obtendremos
un 1 o un 0 segn la tensin fijada en l por la circuitera externa.
Tratemos en primer lugar las salidas, y consideremos el caso ms
comn hoy en da de lgica positiva las tensiones de los 1 lgicos
son mayores que las de los 0. Las especificaciones elctricas de los
150 Entrada/Salida: dispositivos
influencia en ellos que sea posible. De este modo, una entrada aparece
para un circuito externo como una resistencia muy elevada, lo que se
llama una alta impedancia. Dado que es un circuito activo y no una
resistencia, el valor que se especifica es la intensidad mxima que circula
entre el exterior y el circuito integrado, que suele ser despreciable en la
mayor parte de los casos del orden de pocos microamperios o menor
. Los valores especificados son IIHMAX e IILMAX o simplemente IIMAX si
son iguales. En este caso la I significa entrada (input). Segn esto, el
circuito externo puede ser diseado sabiendo la mxima corriente que va
a disiparse hacia el pin, para generar las tensiones adecuadas para ser
entendidas como 0 o 1 al leer el pin de entrada. Para ello se especifican
VIHMIN y VILMAX como la mnima tensin de entrada que se lee como
un 1 lgico y la mxima que se lee como un 0, respectivamente. En
ambos casos, por diseo del microcontrolador, se sabe que la corriente
de entrada est limitada, independientemente del circuito externo.
Qu ocurre con una tensin en el pin comprendida entre VIHMIN y
VILMAX? La lectura de un puerto de entrada siempre devuelve un valor
lgico, por lo tanto cuando la tensin en el pin se encuentra fuera de
los lmites especificados, se lee tambin un valor lgico 1 o 0 que no se
puede predecir segn el diseo del circuito una misma tensin podra
ser leda como nivel alto en un pin y bajo en otro. Visto de otra forma,
un circuito y un sistema en general se debe disear para que fije
una tensin superior a VIHMIN cuando queremos sealar un nivel alto, e
inferior a VILMAX cuando queremos leer un nivel bajo. Otra precaucin
a tener en cuenta con las entradas es la de los valores mximos. En este
caso el peligro no es que se lea un valor lgico distinto del esperado o im-
predecible, sino que se dae el chip. Efectivamente, una tensin superior
a la de alimentacin o inferior a la de masa puede daar definitivamente
el pin de entrada e incluso todo el circuito integrado.
R
VPIN I VD
rojo est entorno a los 1,2V. Por otra parte, a partir de 10mA el brillo
del diodo es adecuado, pudiendo conducir sin deteriorarse hasta 30mA
o ms. Supongamos en nuestro microcontrolador los valores indicados
ms arriba para VOHMIN y VOLMAX, y una corriente de salida superior a
los 20mA. Si queremos garantizar 10mA al escribir un 1 lgico en el
pin, nos bastar con polarizar el LED con una resistencia que limite la
corriente a este valor en el peor caso, es decir cuando la tensin de salida
sea VOHMIN, es decir 4,2V. Mediante la ley de Ohm tenemos:
V 4,2V 1,2V 3V
I= R 10mA = R = R R = 300
VCC
Pin RPULL-UP
de ellos, para un total de 103 lneas de GPIO. Cada una de estas lneas
de entrada/salida es capaz de generar interrupciones por cambio de va-
lor o como lnea dedicada de interrupcin; de configurarse para filtrar o
eliminar rebotes de la entrada; de actuar con o sin pull-up o en colec-
tor abierto. Adems, los pines de salida pueden ponerse a uno o a cero
individualmente, mediante registros dedicados de set o clear, o conjun-
tamente a cualquier valor escribiendo en un tercer registro. Todas estas
caractersticas hacen que cada bloque PIO tenga una gran complejidad,
ocupando un espacio de 324 registros de 32 bits 1.296 direcciones
en el mapa de memoria. Veamos a continuacin los registros ms impor-
tantes y su uso.
que se escribe en una sola escritura el valor, con los unos y ceros deseado,
sobre el registro de salida. Para que este modo no afecte a todos los pines
gestionados por el PIO hasta 32 existe un registro adicional para
seleccionar aqullos a los que va a afectar esta escritura. Para poder
implementar todos estos modos, el conjunto de registros relacionados
con la escritura de valores en las salidas, es el siguiente:
Debouncing Input
Filter Select Register PIO_DIFSR 0x0084
Additional Interrupt
Modes Enable Register PIO_AIMER 0x00B0
Additional Interrupt
Modes Disable Register PIO_AIMDR 0x00B4
Additional Interrupt
Modes Mask Register PIO_AIMMR 0x00B8
Fall/Rise - Low/High
Status Register PIO_FRLHSR 0x00D8
Write Protect
Mode Register PIO_WPMR 0x00E4
Write Protect
Status Register PIO_WPSR 0x00E8
Por otro lado, el RTC est conectado al bus interno del ATSAM3X8E
para que se pueda acceder a los contenidos de sus registros. De esta
forma es posible tanto leer la fecha y hora actuales, modificarlas y con-
figurar las alarmas. Para ello, el RTC dispone de algunos registros de
control encargados de gestionar las funciones de consulta, modificacin
y configuracin del mdulo.
Hora actual
La hora actual se almacena en un registro de 32 bits denominado
RTC_TIMR (RTC Time Register), cuyo contenido se muestra en la Figu-
ra 8.6, donde la hora puede estar expresada en formato de 12 horas ms
indicador AM/PM bit 22 o en formato de 24 horas. Todos los valo-
res numricos estn codificados en BCD (Binary Coded Decimal, decimal
codificado en binario), cuya equivalencia se muestra en el Cuadro 8.7.
Fecha actual
Status Clear
Command Register RTC_SCCR 0x1C
Figura 8.9: Contenido del registro RTC Write Protect Mode Register
Figura 8.11: Contenido del registro RTC Status Clear Command Regis-
ter
Alarmas
El RTC posee la capacidad de establecer valores de alarma para cinco
campos: mes, da del mes, hora, minuto, segundo. Estos valores estn re-
8.2. Gestin del tiempo 177
Eventos peridicos
Adems de las alarmas en instantes programados, como se ha visto
en el apartado anterior, el RTC tambin posee la capacidad de producir
alarmas peridicas con diferentes cadencias configurables a travs del
registro RTC_CR (RTC Control Register), cuyo contenido se muestra en
la Figura 8.8. En sus bits 8 y 9 se encuentra el valor del campo TIMEVSEL
que activa/desactiva la generacin de eventos peridicos de hora y en
los bits 16 y 17 el campo CALEVSEL que activa/desactiva la generacin
de eventos peridicos de calendario.
Un evento de hora puede ser a su vez de cuatro tipos diferentes,
mostrados en el Cuadro 8.9, dependiendo del valor que tome el campo
TIMEVSEL.
Interrupciones en el RTC
El RTC posee la capacidad de generar interrupciones cuando se pro-
ducen una serie de circunstancias:
Actualizacin de fecha/hora.
Evento de tiempo.
Evento de calendario.
Alarma.
Segundo evento de alarma peridica.
se genera por flanco, por lo que al producirse basta con leer el RTT_SR
para evitar que se genere hasta el prximo incremento, comportamiento
tpico de una interrupcin peridica.
La interrupcin de alarma, sin embargo, se produce por nivel mien-
tras el valor del contador sea igual al de la alarma. Leer en este caso
el RTT_SR no hace que deje de sealarse la interrupcin, que se seguir
disparando hasta que llegue otro pulso de la frecuencia de actualizacin.
Este comportamiento no se evita cambiando el valor del RTT_AR pues la
condicin de interrupcin se actualiza con el mismo reloj que incrementa
el temporizador. Esto quiere decir que la interrupcin por alarma est
pensada para producirse una vez y deshabilitarse, hasta que el progra-
ma decida configurar una nueva alarma por algn motivo. Su uso como
interrupcin peridica no es, por tanto, recomendable.
4 12 Memory
management fault Configurable 0x0000 0010
RTI-PIOB.c -
1 void setup() {
2 /* Otra configuracin del sistema*/
8.3. Gestin de excepciones e interrupciones en el ATSAM3X8E 189
3 NVIC_DisableIRQ(PIOB_IRQn);
4 NVIC_ClearPendingIRQ(PIOB_IRQn);
5 NVIC_SetPriority(PIOB_IRQn, 0);
6 PIOsetupInt(EDGE, 1);
7 NVIC_EnableIRQ(PIOB_IRQn);
8 }
9
10 // RTI en C
11 void PIOB_Handler() {
12 /* Cdigo especfico del tratamiento */
190 Entrada/Salida: dispositivos
13 }
RTI-PIOB.s -
1 @ RTI en ensamblador
2 PIOB_Handler:
3 push {lr}
4 /* Cdigo especfico del tratamiento */
5 pop {pc}
ndice
9.1. El entorno Arduino . . . . . . . . . . . . . . . . . . 193
9.2. Creacin de proyectos . . . . . . . . . . . . . . . . . 200
9.3. Problemas del captulo . . . . . . . . . . . . . . . . 206
193
194 Entrada/Salida: ejercicios prcticos con Arduino Due
3V3
R G B
100
10
10
10
GND 13 8 7 6
Figura 9.4: Esquema de la tarjeta de E/S de prcticas de laboratorio
cambiar a 0.
El entorno de programacin de Arduino vase la Figura 9.6 se
presenta como un editor de cdigo en el cual podemos escribir nuestro
programa, guardarlo, compilarlo y subirlo al dispositivo Arduino que
tengamos conectado.
9.2.1. Ejemplo
Como ejemplo bsico vamos a mostrar un programa que hace par-
padear el LED incorporado en la tarjeta Arduino. De momento no es
necesario que la tarjeta est conectada al computador, con lo que esta
fase se puede llevar a cabo sin necesidad de poseer una tarjeta Arduino.
El cdigo es el mostrado en la Figura 9.11:
Una vez introducido el cdigo como texto, podemos comprobar que
es correcto lo cual implica compilarlo mediante el botn de la parte
izquierda de la barra de botones marcado con un crculo en la Fi-
gura 9.6 y que hace aparecer el texto Verificar (tanto en Linux como
en Windows) cuando situamos el cursor sobre l. Tras el proceso de
compilacin se mostrarn los posibles errores detectados indicando el n-
mero de lnea en que se encuentra cada uno de ellos o, si no hay errores,
202 Entrada/Salida: ejercicios prcticos con Arduino Due
blink.s -
1 # blink.s - Parpadeo en ensamblador
2 # Acceso al controlador del PIO B
3
4 .syntax unified
5 .cpu cortex-m3
6 .text
7 .align 2
8 .thumb
9 .thumb_func
10 .extern delay @ No es necesario
11 .global blink @ Funcin externa
12 .type blink, %function
13
14 .equ PIOB, 0x400E1000 @ Dir. base del puerto B
15 .equ SODR, 0x030 @ OFFSET Set Output Data Reg
16 .equ CODR, 0x034 @ OFFSET Clear Output Data Reg
17 .equ CHIPID, 0x400E0940 @ Registro CHIP ID
18 .equ LEDMSK, 0x08000000 @ El LED est en el pin 27
19
20 /* int blink(int times, int delay)
21 r0 = times. Nmero de veces que parpadea
22 r1 = delay. Retardo del parpadeo
23 Devuelve el CHIP_ID, porque s
24 Los parmetros se pasan en r0-r3
25 El valor devuelto en r0 r0-r1 si ocupa 8 bytes
26 Cualquier funcin puede modificar r0-r3
27 El resto se han de preservar */
28
29 blink:
30 push {r4-r7, lr} @ Vamos a usar de r4 a r7
31 @ porque llamamos a delay
32 mov r4, r0 @ r4 contiene el nmero de veces
33 mov r5, r1 @ r5 contiene el retardo a pasar a delay
204 Entrada/Salida: ejercicios prcticos con Arduino Due
blink.h -
1 // Declaracin de las funciones externas
2
3 extern "C" {
4 int blink(int times, int del);
5 }
Este cdigo define una funcin llamada blink que acepta dos argu-
mentos. El primer argumento indica el nmero de veces que se desea que
el LED parpadee y el segundo argumento el periodo de tiempo en mi-
lisegundos que el LED permanecer encendido y apagado en cada ciclo
de parpadeo, es decir, el ciclo completo tendr una duracin del doble
de milisegundos que el valor de este argumento.
Finalmente, el programa principal se encarga de definir los valores
iniciales de las variables y de invocar el cdigo en ensamblador que
efectivamente har parpadear el LED.
blink.ino -
1 /*
2 PROGRAMA: Blink
3 Encendemos y apagamos el led en ensamblador
4 */
5
6 #include "blink.h" // Para declarar la funcin que
9.2. Creacin de proyectos 205
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.1 Conecta a la tarjeta Arduino la tarjeta de prcticas de forma
que los tres pines bajo el LED se correspondan con los pines 6, 7 y 8
y los otros dos pines estn conectados al pin 13 y al pin GND que hay
junto a l. Recuerda conectar el cable al pin 3.3V de la tarjeta Arduino.
Inicia el entorno Arduino y abre el proyecto blink mediante la opcin
Archivo - Ejemplos - 01.Basics - Blink del men. Complalo y sbelo
a la tarjeta. Comprueba que el LED incorporado en la Arduino Due
parpadea de color amarillo, situado aproximadamente entre los dos
conectores USB de la misma e identificado con la letra L.
Sustituye en blink.c las tres apariciones del nmero 13 (como ar-
gumento de la funcin pinMode y de las dos llamadas a la funcin
digitalWrite) por el nmero 6. Compila y sube a la tarjeta el nuevo
programa. Cmo ha cambiado el comportamiento del programa?
9.2 Modifica el programa blink.c para que haga parpadear el LED
de color rojo.
9.3 Descarga del Aula Virtual, seccin Laboratorio, apartado Pro-
gramas para Arduino, los archivos del programa blink_asm, complalo y
ejectalo. Comprueba que el LED de la tarjeta Arduino Due parpadea.
Recordemos que el microcontrolador ATSAM3X8E, incorporado en la
tarjeta Arduino Due que estamos usando, posee varios PIOs (Parallel
Input Output) con varios pines de E/S cada uno de ellos, de forma que
los pines 6, 7 y 8 de la tarjeta Arduino estn fsicamente conectados a
los pines 24, 23 y 22 del PIO C del ATSAM3X8E respectivamente, como
se muestra en el Cuadro 8.5.
Consulta el Cuadro 8.1 para determinar la direccin del registro ba-
se del PIO C y realiza las modificaciones necesarias en blink_asm.c y en
blink.s para que haga parpadear el LED de color rojo. Ten en cuenta
que, mientras que el LED incorporado en la Arduino Due se enciende es-
cribiendo un 1 y se apaga escribiendo un 0 en el puerto correspondiente,
cada componente del LED RGB de la tarjeta de prcticas se encien-
9.3. Problemas del captulo 207
int vector[n];
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.10 Sabiendo que el pulsador incorporado en la tarjeta de prc-
ticas de laboratorio est conectado a un pin del PIOB, qu registro
deberamos leer para detectar que se ha presionado el pulsador?
9.11 El pin al que est conectado el pulsador es el correspondiente
al bit 27 del PIOB. Qu mscara tenemos que aplicar al valor ledo del
registro para determinar la posicin del pulsador?
9.12 De acuerdo con el esquema de conexin del pulsador de la
tarjeta de prcticas mostrado en la Figura 9.4 y si la resistencia de pull-
up de la entrada donde est conectado el pulsador est activada, qu
valor ledo del bit 27 del registro de E/S del PIOB nos indicar que el
pulsador est presionado?
9.13 Descarga el programa pulsa del Aula Virtual y compltalo
para que, mediante consulta de estado, espere la pulsacin del pulsa-
dor de la tarjeta de prcticas para regresar devolviendo el CHIPID del
procesador.
9.14 Modifica el programa anterior para que regrese cuando se
suelte el pulsador tras haberlo pulsado en lugar de cuando se pulse.
9.15 Completa el programa cambia, disponible en el Aula Virtual,
para que con cada pulsacin del pulsador encienda cclicamente el LED
RGB con cada uno de sus tres colores bsicos.
9.16 Para poder modificar los contenidos de los registros de fecha
RTC_CALR y hora RTC_TIMR es preciso detener su actualizacin
escribiendo un 1 en los bits UPDCAL y UPDTIM del registro de control RTC_CR
y esperando la confirmacin de que se ha detenido la actualizacin en
el bit ACKUPD del registro de estado RTC_SR. Puedes consultar los detalles
de este procedimiento en el apartado Actualizacin de la fecha y hora
actuales. Completa el programa cambiahora para configurar el RTC
en el modo de 12 horas con la fecha y hora actuales. Haz que el programa
compruebe los valores de los bits NVCAL y NVTIM para confirmar que la
configuracin ha sido correcta.
9.17 Partiendo del programa alblink disponible en el Aula Vir-
tual, configura una alarma que se active dentro de 8 segundos. Completa
el cdigo proporcionado para que consulte el estado del bit de alarma
y espere a que sta se produzca para regresar al programa en C, el cual
mostrar el instante en que se detect la activacin de la alarma. Ten en
cuenta que tienes que copiar la funcin cambiahora confeccionada en el
apartado anterior en la zona indicada del cdigo fuente proporcionado.
210 Entrada/Salida: ejercicios prcticos con Arduino Due
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.19 En el programa PIOint, disponible en el Aula Virtual, com-
pleta la funcin PIOsetupInt para que configure adecuadamente el
modo de interrupcin seleccionado por los parmetros que se le sumi-
nistran. Una vez completada, comprueba que funciona correctamente
compilando y subiendo el programa a la tarjeta Arduino Due.
9.20 Modifica el cdigo anterior para ir probando todas las posi-
bles combinaciones de los parmetros mode y polarity. Completa
la siguiente tabla, comentando en cada caso cul es el comportamiento
del programa.
FLANCO BAJO
ALTO
NIVEL BAJO
ALTO
CAMBIO BAJO
ALTO
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.26 Consulta en la ayuda de Arduino el funcionamiento de la fun-
cin analogWrite() y, al final de la misma, el enlace Tutorial:PWM.
Cmo se consigue variar la intensidad luminosa del LED mediante la
tcnica PWM
9.27 Descarga el programa pwm del Aula Virtual, complalo y
sbelo a la tarjeta Arduino Due.
9.28 Observa que con cada pulsacin cambia la intensidad del LED
rojo mientras se indica el valor del ciclo de trabajo (Duty Cycle) que
provoca la intensidad observada. Explica qu relacin hay entre el valor
del registro PWM Channel Duty Cycle Register y la intensidad del LED.
9.29 Desplaza la tarjeta Arduino Due con suavidad describiendo
un arco de unos 60 centmetros a una velocidad moderada y observa
el patrn que se visualiza para los diferentes valores del contenido del
registro PWM Channel Duty Cycle Register. Explica cmo estos patrones
obedecen al principio de funcionamiento del PWM visto en el tutorial
de Arduino.
9.30 Cambia el valor actual de la etiqueta CLK (0x0000 0680) por
0x0000 0180. Repite el experimento anterior y comenta las diferencias
apreciadas. Qu cres que ha cambiado?
9.31 Descarga el programa EjemploPWM del Aula Virtual, comp-
lalo y sbelo a la tarjeta Arduino Due. Cmo se consiguen los diferentes
colores en el LED RGB?
9.32 Prueba diferentes valores de FACTRED, FACTGRN y FACTBLU.
Qu efecto tienen estos parmetros en el comportamiento del progra-
ma?
212 Entrada/Salida: ejercicios prcticos con Arduino Due
213