You are on page 1of 259

La programacin en lenguaje ensamblador.

El Lenguaje
Ensamblador
Programacin
ARM Cortex-M3

Vicente Mahout
Publicado por primera vez en 2012 en Gran Bretaa y los Estados Unidos por ISTE Ltd y John Wiley
& Sons, Inc.

Aparte de cualquier trato justo para fines de investigacin o de estudio privado, o la crtica o comentario,
segn lo permitido bajo las leyes de derechos de autor, diseos y patentes Ley 1988, esta publicacin slo
puede ser reproducida, almacenada o transmitida de ninguna forma o por cualquier medio, con la previa
autorizacin por escrito de los editores, o en el caso de reproduccin reprogrfica de conformidad con los
trminos y las licencias expedidas por el CLA. Las investigaciones relativas a la reproduccin fuera de
estos trminos deben ser enviadas a los editores en la direccin: undermentioned

ISTE Ltd, John Wiley & Sons, Inc.


27-37 St George's Road 111 River Street
London SW19 4UE Hoboken, NJ 07030
UK USA
Www.iste.co.uk www.wiley.com

ISTE Ltd 2012

Los derechos de Vicente Mahout a ser identificado como el autor de este trabajo han sido afirmados por l
de conformidad con las leyes de derechos de autor, diseos y Ley de Patentes de 1988.

La biblioteca de Congreso que Cataloga en los datos de la publicacin

Mahout, Vincent.
Lenguaje Ensamblador : ARM Cortex-M3 / Vicente mahout. p. cm.
Incluye referencias bibliogrficas e ndice.
ISBN 978-1-84821-329-6
1. Los sistemas informticos integrados. 2. Los microprocesadores. 3. Lenguaje Ensamblador
(lenguaje de programa informtico) I. TTULO.
TK7895.E42M34 2012
005.2--dc23
2011049418

British Catalogacin por la Biblioteca de


Un registro de la CIP para este libro est disponible en la Biblioteca Britnica
ISBN: 978-1-84821-329-6

Impreso y encuadernado en Gran Bretaa por CPI Group (UK) Ltd., Croydon, Surrey CR0 4AA
Tabla de
contenido

Prefacio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ix
. . . . . . . .
1
Captulo 1. Descripcin general de la arquitectura Cortex-M3 . . . . . . .
1.1. El lenguaje ensamblador versus el ensamblador . . . . . . . . . . . . . . . . . . 1
. . . . . . . . .
1.2. El mundo del brazo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2.1. Cortex-M3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2.2. El ncleo Cortex-M3 de STM32. . . . . . . . . . . . . . . . . . . . . . 7

Captulo 2. El ncleo de Cortex-M3 . . . . . . . . . . . . . . . . . . . . . 15


. . . .
2.1. Modos, privilegios y miembros . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.2. Los registros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2.1. Los registros R0 a R12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.2.2. El registro R13, tambin conocida como SP . . . . . . . . . . . . . . . . . 19
..
2.2.3. El registro R14, tambin conocido como LR . . . . . . . . . . . . . . . . . 20
..
2.2.4. El R15 o PC Registro. . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.2.5. La xPSR registrar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

Captulo 3. La correcta utilizacin de las directrices de la Asamblea . . . . 25


. . . . . . . . . . .
3.1. El concepto de la directiva . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.1.1. Convenciones tipogrficas y el uso de smbolos . . . . . . . . . . . . . 26
3.2. Estructura de un programa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.2.1. El rea secciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.3. Una seccin de cdigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.3.1. Etiquetas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.3.2. Nemotcnica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.3.3. Los operandos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.3.4. Comentarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.3.5. Procedimiento. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
6 La programacin en lenguaje
ensamblador.

3.4. La seccin de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36


3.4.1. Simple reserva . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.4.2. Reserva con inicializacin . . . . . . . . . . . . . . . . . . . . . . 37
3.4.3. Inicializacin de datos: El diablo est en los detalles . . . . . . . . . . . . 39
. . Es que todos los? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.5. 39
3.5.1. Las directivas de administracin de memoria . . . . . . . . . . . . . . . . . . 40
. . . Directivas de gestin de proyectos . . . . . . . . . . . . . . . . . . . . . .
3.5.2. 41
3.5.3. Directivas de diversos y variados . . . . . . . . . . . . . . . . . . . . . . . 44

Captulo 4. Los operandos de las instrucciones . . . . . . . . . . . . . . . 47


. . . . . . . . .
4.1. La constante y cambio de nombre. . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.2. Los operandos para instrucciones comunes . . . . . . . . . . . . . . . . . . . . . . 49
4.2.1. Utilizacin de registros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.2.2. El operando inmediato . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.3. Memory access operandos: modos de direccionamiento . . . . . . . . . . . . . 57
. . 4.3.1.
. El concepto de puntero . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
4.3.2. modos de direccionamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

Captulo 5. La instruccin Set . . . . . . . . . . . . . . . . . . . . . . . . 63


. . . . . . .
5.1. Gua de lectura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
5.1.1. Lista de posibles "condicin" sufijos. . . . . . . . . . . . . . . . . . . 65
5.2. Instrucciones aritmticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
5.3. Instrucciones de manipulacin de bits y lgica . . . . . . . . . . . . . . . . . . 70
5.4 Instrucciones de transferencia interna . . . . . . . . . . . . . . . . . . . . . . . . . . 75
5.5. Las instrucciones de la prueba . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
. . Instrucciones de sucursal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.6. 77
5.7. Cargar/guardar instrucciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
5.7.1. Simples transferencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
5.7.2. Las transferencias mltiples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
5.7.3. El acceso a la pila del sistema . . . . . . . . . . . . . . . . . . . . . . . . 84
5.8. "Sistema" instrucciones y otros . . . . . . . . . . . . . . . . . . . . . . . 85

Captulo 6. Algoritmos y estructuras de datos . . . . . . . . . . . . . . . . 87


. . .
6.1. Diagrama de flujo del algoritmo versus . . . . . . . . . . . . . . . . . . . . . . . . 87
. . Estructuras alternativas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2. 89
6.2.1. Simple (o reducir) alternativa. . . . . . . . . . . . . . . . . . . . . 89
6.2.2. Alternativa completa . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
6.2.3. Caso especial de la alternativa . . . . . . . . . . . . . . . . . . . . . . 93
6.2.4. Eleccin mltiple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
6.3. Estructuras iterativas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
6.3.1. La repeticinhasta loop . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Tabla de contenido Vii

6.3.2. Al mismo tiempo bucle Do . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102


6.3.3. El bucle para . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
6.4. Condiciones compuesto. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
6.4.1. Alternativa con y . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
6.4.2. Iteracin con y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
6.4.3. Alternativa con o . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
6.4.4. Iteracin con o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
6.5. Estructura de datos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
6.5.1. Tabla en una sola dimensin . . . . . . . . . . . . . . . . . . . . . . . . . . 111
6.5.2. Las tablas de dimensiones mltiples . . . . . . . . . . . . . . . . . . . . . . 112
6.5.3. Registro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
6.5.4. La no-dimensional, tabla de cadena de caracteres. . . . . . . . . . . . . . . 113
..
6.5.5. La cola . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
6.5.6. Pila . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115

Captulo 7. Modularidad interior . . . . . . . . . . . . . . . . . . . . . . 119


. . . . .
7.1. Detallando el concepto de procedimiento . . . . . . . . . . . . . . . . . . . . . . 119
7.1.1. Simple llamada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
7.1.2. Llamadas anidadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
7.1.3. "Hilo Rojo" ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
7.2. Procedimiento argumentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
7.2.1. Utilidad de argumentos. . . . . . . . . . . . . . . . . . . . . . . . . . 123
7.2.2. Argumentos por valor y por referencia . . . . . . . . . . . . . . . . . . 123
7.2.3. Pasar argumentos por registros generales . . . . . . . . . . . . . . . . . 123
7.2.4. Pasar argumentos por una pila . . . . . . . . . . . . . . . . . . . . . . . 126
7.2.5. Pasar argumentos por la pila del sistema . . . . . . . . . . . . . . . . . 133
7.2.6. sobre el arte de la mezcla . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
7.3. Los datos locales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
7.3.1. Reserva simple de datos locales . . . . . . . . . . . . . . . . . . . . . 137
7.3.2. Utilizando una lista encadenada. . . . . . . . . . . . . . . . . . . . . . . . . . . 143
..
Captulo 8. Gestin de excepciones. . . . . . . . . . . . . . . . . . . . . . 147
. . . . .
8.1. Qu sucede durante el restablecimiento? . . . . . . . . . . . . . . . . . . . . . . . . 148
. . Las posibles excepciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.2. 151
8.2.1. Capturas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
8.2.2. interrumpe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
8.3. Gestin de prioridad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
8.3.1. Los niveles de prioridad y subniveles . . . . . . . . . . . . . . . . . . . . . . . 162
8.3.2. El mecanismo anidadas . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
8.4. Entrada y retorno en el procesamiento de excepciones . . . . . . . . . . . . . . 167
. . 8.4.1.
.. Re-enrutamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
8.4.2. Volver. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
8 Assembly Language Programming

8.4.3. "Tail-encadenamiento" y "de llegada tarda" . . . . . . . . . . . . . . . . . 169


..
8.4.4. Otros registros tiles para el NVIC . . . . . . . . . . . . . . . . . . . 170

Captulo 9. En la lista de ejecutables: modularidad externo . . . . . . . . 173


9.1. Modularidad externo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
9.1.1. Ejemplo genrico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
9.1.2. Montaje por piezas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
9.1.3. Ventajas de montaje por piezas . . . . . . . . . . . . . . . . . . . . 178
9.1.4. Smbolos externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
9.1.5. Importar y exportar directivas . . . . . . . . . . . . . . . . . . . . 181
9.2. La funcin del ensamblador . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
9.2.1. Los archivos producidos por el ensamblador . . . . . . . . . . . . . . . . . . . 183
.9.2.2.
. Colocacin contadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
9.2.3. Primer paso: tabla de smbolos . . . . . . . . . . . . . . . . . . . . . . . . . . 185
9.2.4. Segundo paso: traduccin . . . . . . . . . . . . . . . . . . . . . . . . . . 186
9.2.5. Tabla de reubicacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
9.3. El papel del vinculador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
9.3.1. Principio de funcionamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
9.3.2. Los productos del vinculador . . . . . . . . . . . . . . . . . . . . . . . . . 190
9.4. El cargador y la unidad de depuracin . . . . . . . . . . . . . . . . . . . . . . 196

Apndices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
. . . . . .
Apndice A. Instruction Set - Lista Alfabtica . . . . . . . . . . . . . . . 201
. .
Apndice B. SysTick Timer . . . . . . . . . . . . . . . . . . . . . . . . . 209
. .
Apndice C. Ejemplo de "Bootstrap" Archivo. . . . . . . . . . . . . . . 217
. . . . .
Apndice D. El Ensamblador GNU . . . . . . . . . . . . . . . . . . . . . 227
. . . . .
Bibliografa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
. . . . . .
ndice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
. . . . . . . .
Prefacio

Para poder planificar y escribir este tipo de libros, usted necesita un buen ambiente
de trabajo. En mi caso, yo era capaz de beneficiarse de las mejores condiciones de
trabajo para esta empresa. En trminos de infraestructura y material, el Instituto
Nacional de Ciencias Aplicadas de ToulouseToulouse, Francia (Instituto Nacional de
Ciencias Aplicadas), y en particular de su Departamento de Ingeniera Elctrica e
Informtica, nunca ha dudado en invertir en equipo de ingeniera de sistemas, de
modo que la formacin de nuestros futuros ingenieros siempre ser capaz de
mantenerse al da con los rpidos cambios tecnolgicos. Deseo expresar mi profundo
agradecimiento a esta institucin. Estos sistemas no han ascendido a mucho menos, a
lo largo de los aos, haba un equipo de docentes y tcnicos aportando su entusiasmo
y dinamismo para llevarlas a la prctica. Las siguientes pginas contienen tambin
el duro trabajo de Pascal Acco, Guillaume Auriol, Pierre- Emmanuel Hladik, Didier
Le Botlan, Jos Martn, Sbastien Di Mercurio y Thierry Rocacher. Les doy las
gracias sinceramente. Las dos ltimas respetuoso y amable nods vaya a Franois y
Bernard Pompignac Faur, quien, antes de la jubilacin, hizo mucho trabajo para
fertilizar esta tierra ahora floreciente.

Al escribir un libro sobre el lenguaje ensamblador de un procesador , sabemos de


antemano que no se registrar en la posteridad. Por su propia naturaleza, un lenguaje
ensamblador tiene la misma esperanza de vida que el procesador admite -quizs de 20
aos, en el mejor de los casos. Y lo que es ms, este tipo de programacin no es,
obviamente, utilizados para el desarrollo de proyectos de software y por lo tanto es de
poca trascendencia.

La programacin en lenguaje ensamblador, sin embargo, es un paso indispensable


para comprender el funcionamiento interno de un procesador . Esta es la razn por la
que todava se ensea en equipo industrial de formacin, y en particular en la
formacin de los ingenieros. Es evidente que un buen conocimiento terico de un
determinado lenguaje ensamblador, combinado con una fase de formacin prctica,
facilita el aprendizaje de otros lenguajes de programacin, si son el conjunto de
idiomas de otros procesadores o lenguajes de alto nivel.
10 Assembly Language
Programming

As, este libro pretende diseccionar la programacin en lenguaje ensamblador de


un controlador construido alrededor de un ARM Cortex-M3 de ncleo. La eleccin
de este controlador descansa sobre la voluntad de explicar:
- un procesador de 32 bits: la eleccin del diseador del brazo es esencial en el
mundo de 32 bits. Este tipo de procesador ocupa, por ejemplo, el 95% del mercado en
el mbito de la telefona mvil.
- un procesador de reciente concepcin y arquitectura: las primeras licencias para
Cortex-M3 estn fechadas en octubre de 2004 y las de STMicroelectronics'
microcontroladores Flash de 32 bits (STM32) recibieron en junio de 2007.
- Un procesador adaptado al mundo integrado, basado en la observacin de que el 80%
La actividad de desarrollo de software implica sistemas integrados.

Este libro ha sido escrito para ser lo ms genrico posible. Es, sin duda, basada en
la arquitectura de conjunto de instrucciones y Cortex-M3, pero con la intencin de
explicar los mecanismos bsicos de la programacin en lenguaje ensamblador. De
esta manera podemos utilizar de forma sistemtica la programacin modular para
mostrar cmo estructuras algortmicas bsicas pueden ser programados en lenguaje
ensamblador. Este libro tambin presenta muchos ejemplos ilustrativos, lo que
significa que tambin es prctico.
Captulo 1

Descripcin general de la arquitectura


Cortex-M3

Un programa informtico se define generalmente como una secuencia de


instrucciones que actan sobre los datos y devolver un resultado esperado. En un
lenguaje de alto nivel, la secuencia y los datos se describen en un acto simblico, la
forma abstracta. Es necesario utilizar un compilador para traducirlas en instrucciones
de lenguaje de mquina, que slo se entiende por el procesador. El lenguaje
ensamblador es directamente derivado del lenguaje mquina, por lo tanto, cuando la
programacin en lenguaje ensamblador, el programador es obligado a ver las cosas
desde el punto de vista del procesador.

1.1. El lenguaje ensamblador versus el ensamblador

Cuando se ejecuta un programa, el procesador de un ordenador obedece a una serie


de rdenes numricos - Instrucciones - que se leen desde la memoria: estas
instrucciones se codifican en formato binario. La coleccin de instrucciones en la
memoria conforma el cdigo del programa que est siendo ejecutado. Otras reas de
memoria son tambin utilizados por el procesador durante la ejecucin de cdigo: una
zona que contenga los datos (variables, constantes) y una zona que contiene la pila del
sistema, el cual es utilizado por el procesador para almacenar, por ejemplo, los datos
locales al llamar a los subprogramas. Cdigo, datos y la pila del sistema son los tres
elementos fundamentales de todos los programas durante su ejecucin.

Es posible programar directamente en lenguaje mquina, es decir, escribir el bit las


secuencias de instrucciones en lenguaje mquina. En la prctica, sin embargo, esto
no es realista, incluso cuando se utiliza una secuencia de comandos ms condensada
gracias a notacin hexadecimal ( base 16) de numeracin para las instrucciones. Por
lo tanto, es preferible utilizar un lenguaje ensamblador. Esto permite que el cdigo
sea representada por nombres simblicos, adaptadas a la comprensin humana, que
corresponden a las instrucciones en lenguaje mquina.
2 Assembly Language Programming Overview of Cortex-M3 Architecture 2

El lenguaje ensamblador tambin permite al programador a reservar el espacio


necesario para que el sistema de pila y esferas de datos dndoles un valor inicial, si es
necesario. Tome este ejemplo de una instruccin para copiar en el no. 1 Registro
general de un procesador con el valor 170 (AA en hexadecimal). Aqu est
escrito usando la sintaxis del lenguaje ensamblador estudi aqu:

EJEMPLO 1.1.- Una sola lnea de


cdigo

MOV R1, #0xAA ; copia (mover) con un valor de 170 (AA en


hexa)
; en el registro
R1

En la misma instruccin, representada en lenguaje mquina hexadecimal (base),


est escrito: E3A010AA. El nombre simblico MOV lleva el nombre mnemotcnico.
R1 y
#0xAA son los argumentos de la instruccin. El punto y coma indica el inicio de un
comentario que termina con la lnea actual.

El ensamblador es un programa encargado de traducir el programa de la Asamblea


en el idioma en que est escrito en lenguaje de mquina. A la entrada, recibe un archivo
de cdigo fuente que est escrito en lenguaje ensamblador, y crea dos archivos: el
archivo objeto que contenga lenguaje mquina (y la informacin necesaria para la
fabricacin de un programa ejecutable), y la impresin general archivo que contiene
un informe que detalle el trabajo realizado por el ensamblador.

Este libro aborda el lenguaje ensamblador en general, pero se centra en los


procesadores basados en Cortex-M3, tal y como establecen las mquinas de avanzada
de RISC (abreviado DEL BRAZO). Diferentes diseadores (Freescale,
STmicroelectronics, NXP, etc.) y, a continuacin, integrar esta estructura
en controladores que contienen memoria y varios perifricos as como este ncleo de
procesador. Parte de la documentacin relativa a este ncleo de procesador est
disponible en formato PDF en www.arm.com.

1.2. El mundo del brazo

El brazo no fabrican semiconductores directamente, sino que proporciona licencias


para ncleos de microprocesador con arquitectura RISC de 32 bits.

Esta empresa con sede en Cambridge esencialmente apunta a proporcionar


sistemas integrados de semiconductores para el mercado. Para dar una idea de la
posicin de este diseador en este mercado, el 95% de los telfonos mviles en 2008
fueron hechas con basado en ARM
3 Assembly Language Programming Overview of Cortex-M3 Architecture 3

Los procesadores. Cabe sealar tambin que el A4 y A5, los procesadores fabricados
por Apple y utilizado en su iPad tabletas grficas, estn basados en los procesadores
ARM Cortex-Type una.

Desde 1985, y su primera arquitectura (llamado ARM1, ARM arquitecturas)


ciertamente han cambiado. La arquitectura en la que Cortex-M3 se basa se llama
ARMV7-M.

La coleccin del brazo est estructurado en torno a cuatro grandes familias


de productos, por lo que muchas de las licencias se han presentado 1:
- el brazo 7 family (173 licencias);
- el brazo 9 family (269 licencias);
- el brazo de 10 familias (76 licencias);
- El Cortex-una familia (33 licencias);
- la familia Cortex-M (51 licencias, de las cuales 23 son para la versin M3);
- la familia Cortex-R (17 licencias).

1.2.1. Cortex-M3

Objetivos Cortex-M3, en particular, sistemas integrados que requieren


importantes recursos (32 bits), pero para estos los costos (de produccin, desarrollo y
consumo) debe reducirse. La primera ilustracin global (vase la figura 1.1) de Cortex-
M3, que se encuentra en la documentacin tcnica de este producto, es un diagrama
funcional. Aunque simple en su representacin, cada bloque podra perplejo a un
novato. Sin conocer todos los detalles y todas las sutilezas, es til tener una idea de las
principales funciones realizadas por los diferentes bloques de la arquitectura.

1.2.1.1. Unidades
Ejecutivas
Estas unidades conforman la parte principal del procesador: la parte que es
fundamentalmente necesario para ejecutar las aplicaciones y realizar ellos mismos o
sus funciones de software:
- CM3CORE: es el ncleo mismo. Esta unidad contiene diferentes registros, todos
los mecanismos de la instruccin de lectura y escritura y los datos en el formulario de
la aritmtica y

1 nmeros desde el tercer trimestre de 2010.


4 Assembly Language Programming Overview of Cortex-M3 Architecture 4

Unidad lgica para la correcta ejecucin de instrucciones diferentes. El


funcionamiento de este bloque ser explicado en detalle en el Captulo 2. Es necesario
comprender su mecanismo a fin de escribir programas en lenguaje ensamblador.
- Controlador de interrupcin vectorial anidados (NVIC): Cortex-M3 est pensado
para ser incrustado en un controlador , que incluye las unidades perifricas para
permitir la interaccin con el mundo exterior. Estas unidades pueden ser vistos como
independientes micromachines. Los intercambios entre ellos y Cortex-M3 debe por
consiguiente ser rtmicas y organizada de manera que la secuencia de tareas que
cumple con las normas (el concepto de prioridades) y determinismo fijados de
antemano por el programador. NVIC desempea el papel de "director". Es el
responsable de la recepcin, clasificacin y distribucin de las diferentes solicitudes
de interrupcin generada por la coleccin de unidades de controlador . Tambin
administra los eventos que amenazan el buen funcionamiento del cdigo que se
ejecutan (reset, problema del bus de memoria, la divisin por 0, etc.).

Figura 1.1. Cortex-M3 diagrama funcional

- Unidad de Proteccin de memoria (MPU): Este bloque es opcional - Un diseador


utilizando Cortex-M3 para hacer sus controlador puede optar por no aplicar esta
funcin. Este bloque permite la asignacin de lectura y/o escritura a determinadas
zonas de memoria. De esta manera, cuando los diferentes tareas independientes de
software se ejecutan en paralelo (o, ms precisamente en el reparto de los recursos
comunes del procesador), es posible asignar una zona de memoria para cada tarea que
es inaccesible para las dems tareas. Por ello, este mecanismo permite a los
programadores acceso a memoria segura. Ella
5 Assembly Language Programming Overview of Cortex-M3 Architecture 5

Normalmente va de la mano con el uso de un sistema operativo en tiempo real (o


no) de la capa de software.
- Bus MATRIX: Esta unidad es una especie de gigantesca multiplexada inteligente.
Permite conexiones a los buses externos:
- El bus ICode (32 bits AHB-Lite tipo2) que lleva las asignaciones de memoria
asignada al cdigo e instrucciones;
- el DCode (bus de 32 bits tambin AHB-Lite tipo) que se encarga de la
lectura/escritura en memoria datos zonas;

- el sistema de bus de 32 bits (nuevamente AHB-Lite), que se ocupa de todos los


sistemas de acceso al espacio;
- El bus perifrico privado (PPB): todos los perifricos que figura en
el controlador se agregan a la arquitectura Cortex-M3 por el diseador. Brazo
diseado un bus especfico para permitir intercambios con perifricos. Este bus contiene
32 bits, pero en este caso es el avanzado bus perifrico (APB) tipo. Esto corresponde
a otro bus protocol (que puede conocer es menos eficiente que la abeja africanizada
tipo, pero es ms que suficiente para el acceso a las unidades perifricas). Cabe sealar
que el autobs matriz juega un papel importante en la transmisin de informacin til
para el desarrollo de unidades, que se mencionan en la siguiente seccin.

1.2.1.2. Unidades de desarrollo


El desarrollo de programas es un importante y especialmente prolongado paso en
el ciclo de desarrollo de una aplicacin incrustada. Lo que es ms, si el proyecto tiene
imperativos de certificacin, es necesario que las herramientas (software y/o material)
y permite el mximo control de los eventos que ocurren en cada ciclo de reloj estn a
su disposicin. En Cortex-M3, las diferentes unidades introdujo brevemente a
continuacin corresponden a estas funciones de vigilancia. Ellos estn directamente
implantados en el silicio del circuito, lo que les permite utilizar estas herramientas de
desarrollo a un nivel material. Una capa de software externo es necesario, sin
embargo, recuperar y procesar la informacin emitida por estas unidades. La idea
genrica que subyace en la introduccin de soluciones hardware es ofrecer al
programador la capacidad para probar y mejorar la fiabilidad de la (o
certificar) su cdigo sin realizar ningn cambio. Es conveniente (y habitual) para
insertar algunos print ("Hola yo estaba aqu") en una estructura de software para
comprobar que la ejecucin pasa a travs de esta estructura. Hecho esto, se introduce
una modificacin de cdigo, lo cual puede modificar el comportamiento global del
programa. Esto es especialmente cierto cuando la gestin del tiempo es fundamental
para el sistema, que por

2 avanzado bus de alto rendimiento (AHB) es un protocolo de bus de microcontrolador trado por
Brazo.
6 Assembly Language Programming Overview of Cortex-M3 Architecture 6

Los sistemas integrados controlados por un controlador , casi siempre es el caso.


Las unidades relativas a funciones de vigilancia en Cortex-M3 incluyen:
- Flash parche y breakpoint (FPB): la FPB es la funcin ms bsica para este
proceso. Est vinculado con el concepto de un punto de parada (breakpoint), lo que
impone una parada en una lnea de cdigo (es decir, una instruccin en el caso del
lenguaje ensamblador) situado de antemano. Esta unidad se utiliza para marcar
instrucciones para que cuando entren en vigor, el procesador se pone a s mismo en
un determinado modo de funcionamiento: modo de depuracin. Software de
desarrollo (y otras piezas de software que usan) puede, por tanto, observar el estado del
procesador e influir directamente en la ejecucin del programa en curso.
- Datos Punto de observacin y seguimiento (DWT): el concepto de un "punto de
observacin" es el equivalente al concepto de un punto de parada para los datos. El
DWT detiene la ejecucin del programa cuando se trabaja sobre datos marcados en
lugar de una instruccin marcada. Esta accin puede estar en la lectura, la escritura, la
transmisin de valores, etc. La unidad tambin puede enviar peticiones a
la ITM y ETM unidades.

- Embedded Trace Macrocell (ETM): el concepto de trace incluye la capacidad de


hardware para grabar una secuencia de eventos durante la ejecucin del programa. La
recuperacin de estas grabaciones permite al programador para analizar la marcha del
programa, ya sea bueno o malo. En el caso de ETM, slo la informacin en las
instrucciones se almacenan en un primero en entrar, primero en salir (FIFO) tipo de
estructura. Como con la MPU unidad, esta unidad es opcional.

- Instrumentacin Trace Macrocell (ITM): Esta unidad tambin permite la


recopilacin de informacin de rastreo sobre aplicaciones (software, hardware o
tiempo). La informacin es ms limitada que con la unidad de ETM, pero que es muy
til a la hora de aislar un crculo bug. Esto es especialmente cierto si el ETM opcional
no est presente.

- avanzado bus de alto rendimiento Puerto de acceso (AHB-AP): este es un


(Entrada/Salida) Puerto dentro del Cortex-M3, que est diseado para depurar. Permite
el acceso a todos los registros y todo el espacio de memoria direccionable. Tiene
prioridad en las polticas de arbitraje del bus matrix. Esta unidad se conecta aguas
arriba por el cable serie JTAG (Joint Test Action Group) (SW/Puerto JTAG), que es
la interfaz (con sus capas fsicas) que conecta con el mundo exterior, equipado con
su parte de la sonda JTAG. El JTAG protocol es un protocolo estandarizado utilizado
por casi todos los fabricantes de semiconductores.

- Seguimiento de la unidad de interfaz de puerto (TPUI): El TPUI desempea el


mismo papel en trace funciona como el SW/JTAG desempea en funciones de
depuracin. Su existencia est principalmente vinculado al hecho de que es
necesario ordenar el mundo externo grabaciones recogidas por la ITM. Hay un reto
adicional, sin embargo, cuando una unidad de ETM est presente, como tambin debe
gestionar los datos almacenados all. Su papel es secundario
7 Assembly Language Programming Overview of Cortex-M3 Architecture 7

Por lo tanto para combinar y dar formato a esta doble corriente de los datos antes de
transmitirlos al puerto. En el mundo exterior, es necesario usar un analizador de
puertos de traza para recuperar los datos.

1.2.2. El ncleo Cortex-M3 de STM32

Como ya se ha indicado, el brazo no directamente hacer semiconductores.


El ncleo del controlador diseos son vendidos bajo licencia a diseadores que
agregar todas las unidades perifricas que componen la "interfaz con el exterior". Por
ejemplo, la familia STM32 de controladores, realizados por STMicroelectronics,
contiene la mejor venta controladores empleando Cortex-M3. Como toda buena
familia de controladores de , la familia STM32 est disponible en muchas versiones.
A principios de 2010, el catlogo de STMicroelectronics ofrece los productos
mostrados en la Figura 1.2.

Figura 1.2. Los productos de la


familia STM32
8 Assembly Language Programming Overview of Cortex-M3 Architecture 8

1.2.2.1. Funcionalida
d
La seleccin de la versin adecuada de controller puede ser un paso importante
en la fase de diseo del proyecto: en funcin de las necesidades (en trminos de la
funcin, el nmero de entrada/salida, etc.), sino tambin sobre las limitaciones
adecuadas (coste, consumo, tamao, etc.), cada versin del procesador ser ms o
menos bien adaptada al proyecto. Nuevamente, el propsito de este libro es no entrar
en detalles acerca de la funcin de los aspectos perifricos de la controlador. No
obstante, es til para tener una visin global del circuito que finalmente sern
programados, por lo que no estn sorprendidos por esas cosas bsicas como, por
ejemplo, el direccionamiento de memoria. Desde un punto de vista funcional, la
figura 1.3 muestra cmo STMicroelectronics ha "vestidas" Cortex-M3 para crear un
procesador (STM32F103RB versin es mostrado aqu). La primera observacin
importante es que,
Inevitablemente, no todas las funciones ofrecidas por este controlador estn
disponibles simultneamente.
Normalmente varias unidades comparten las clavijas de salida. Por lo tanto,
dependiendo de la configuracin que el programador, impone ciertas funciones de
facto debe estar disponible para la aplicacin. Slo un conocimiento profundo de
un procesador determinado permitirn al programador a conocer, a priori, si la
versin escogida ser suficiente para las necesidades de la aplicacin que se
desarrolla. La cuestin de la eleccin de la mejor versin es, por lo tanto, lejos de ser
trivial.

Figura 1.3. Descripcin funcional de los STM32F103RB


9 Assembly Language Programming Overview of Cortex-M3 Architecture 9

Mirando el esquema del STM32F103RB procesador, podemos ver que tiene


Elementos de diseo del brazo en su ncleo de procesador, a saber:
- una etapa de potencia y circuitos de reloj. Esto hace que sea posible colocar el
procesador en modo "sleep" y permitir el acceso a frecuencias diferentes (lo que es
interesante para gestin de temporizador en particular).
- La adicin de Flash y RAM. La cantidad de memoria presente en el caso es una
de las variables que flucta ms, dependiendo de qu controlador es elegido. El
STM32F103RB versin tiene 128 KB de memoria Flash, que, para ponerlo en
perspectiva, puede representar hasta 65.000 lneas de cdigo escrito en lenguaje
ensamblador
(suponiendo que una instruccin est codificado en 16 bits);
- directores desarrollado en la hora del sistema, incluida la Systick timer de 24 bits
y un sistema de despertador automtico cuando el procesador ha pasado a modo de
"reposo". Estas unidades tienen una innegable utilidad durante el uso del kernel en
tiempo real.

STMicroelectronics agrega las siguientes funciones:


- el tiempo y/o gestin de cmputo perifricos;
- gestin de la seal analgica de los perifricos. Estos son CONVERTIDORES
ANALOGICO/numrico para adquirir las cantidades analgicas, y representan la
PWM (modulacin por ancho de pulso) gerentes para enviar seales asimilable a las
cantidades analgicas;
- perifricos de entrada/salida digital. Estos 51 de Entrada y salida de propsito
general (GPIO) perifricos son los TTL (Transistor-Transistor Logic) puertos de
entrada/salida y los otros 16 seales de entrada digital que puede transmitir
una peticin de interrupcin.
- Comunicacin de los perifricos. Diferentes protocolos actuales estn presentes
en este chip para comunicaciones a travs de un enlace en serie (sncrono Universal
Asynchronous Receiver Transmitter (USART), Bus Serie Universal (USB) o un bus
industrial (I2C, red de rea de controlador (CAN), Serial Peripheral Interface (SPI).

1.2.2.2. Espacio de memoria


Gestin del espacio de memoria es, sin duda, el aspecto ms complicado para ser
administrada cuando se desarrolla un programa en lenguaje ensamblador.
Afortunadamente, una serie de directivas de montaje asociados con una
potente enlazador hacer esta gestin relativamente simple. Sin embargo, es til tener
una idea clara de la asignacin de memoria para trabajar con pleno conocimiento de los
hechos, mientras los pases en desarrollo (y depuracin) del programa. De hecho, los
registros del procesador regularmente contienen cantidades que corresponden a las
direcciones. Cuando el programa no se comporte del modo deseado (un desagradable
error, claro!), es til saber si las cantidades producidas son aquellos que podan
esperarse. Cortex-M3 tiene 4 GB de memoria (espacio de direcciones consecutivas
de bus de 32 bits). Una direccin de memoria corresponde a un byte. De ello se deduce
que una mitad-palabra ocupa dos direcciones y una palabra (32 bits) ocupa cuatro
direcciones de memoria.
10 Assembly Language Programming Overview of Cortex-M3 Architecture 10

Por convencin, el almacenamiento de datos est dispuesto segn el estndar de


little endian, donde el byte menos significativo de una palabra o media palabra se
almacena en la direccin ms baja, y volvemos a las direcciones altas tomando la serie
del componente de bytes que componen el nmero almacenado en la memoria. La
figura 1.4 muestra cmo, en el little endian estndar, colocacin de memoria de
palabras y palabras de media es administrado.

La arquitectura es de tipo Harvard-, lo que se traduce en una divisin que separa


el acceso de cdigo de acceso a datos. La figura 1.5 muestra cmo esta divisin est
planificado. Las otras zonas (Perifrico, externos, etc.) imponer la colocacin en el
espacio de direccionamiento de diferentes unidades, como se presenta en la Figura 1.3.

Una caracterstica que debe tenerse en cuenta preocupaciones memory access


- bandas de bits. Esta tcnica se encuentra tanto en la memoria de acceso aleatorio
esttica (SRAM) zona (entre las direcciones 020000000 y 02000ffff para la zona
de la banda de bits y direcciones de 022000000 y 023FFFFFF para el alias) y
la zona perifrica (entre las direcciones 040000000 y 04000ffff para la zona de la
banda de bits y direcciones de 042000000 y 043FFFFFF para el alias). Estas
cuatro zonas son esquematizados por la eclosin en el mapeo de memoria en la Figura
1.5. Esta tcnica permite al programador modificar directamente (establecer o
restablecer) bits situado en las direcciones dentro de la zona de bandas de bits.

En la figura 1.4. Convencin little-


endian
11 Assembly Language Programming Overview of Cortex-M3 Architecture 11

Figura 1.5. Cortex-M3 de mapeo de memoria


12 Assembly Language Programming Overview of Cortex-M3 Architecture 12

Figura 1.6. Principio de bandas de bits para la primera direccin de SRAM

Cul es el problema? En la medida en que la arquitectura no puede actuar


directamente sobre los bits en la memoria, si queremos modificar un poco en una zona
de memoria sin esta funcin, es necesario:
1) recuperar la palabra de la memoria;
2) modificar el bit (mediante la aplicacin de una mscara binaria, por ejemplo);
3) Vuelva a escribir la palabra en la memoria.
13 Assembly Language Programming Overview of Cortex-M3 Architecture 13

El brazo est diseado para que coincida con la direccin de una palabra (en la
zona de alias) con un poco de bits (en la zona de bandas). As que cuando el
programador escribe un valor en la zona de alias, que equivale a la modificacin de
las bandas de bits bit correspondiente al poco peso cero que acaba de escribir. Por el
contrario, leyendo el bit menos significativo de una palabra en la zona de alias permite
que el programador conoce el estado lgico del bit correspondiente en la zona de
bandas de bits (vase la figura 1.6). Cabe sealar que esta tcnica no utiliza la
memoria RAM en la medida en que las zonas de alias son imaginarios: fsicamente
no corresponden a las ubicaciones de memoria - que slo utilizan direcciones de
memoria, pero con 4 GB de posibles direcciones esta prdida es de poca trascendencia.
Captulo 2

El ncleo de Cortex-M3

El captulo anterior mostraba cmo el programador poda romper las diferentes


unidades presentes en un controlador como STM32 desde un punto de vista
funcional. Ahora es el momento de ahondar un poco ms en el ncleo Cortex-M3, y
explicar en detalle el contenido de la CM3cuadro bsico, tal como se muestra en la
Figura 2.1.

No tendra sentido crear una rplica (que sera incompleto, debido a la


simplificacin necesaria) de los contenidos de los diversos manuales de referencia
[brazo brazo 06A, 06B, 06C DEL BRAZO] que dar explicaciones detalladas de las
funciones corticales. Tambin sera intil, sin embargo, reclamar a programar en
lenguaje ensamblador sin tener una idea razonablemente precisa de su estructura. Este
captulo, por lo tanto, intenta presentar los aspectos de la arquitectura necesaria para
razon
Programacin de un controlador .

2.1. Los modos, privilegios y estados

Cortex-M3 se puede poner en dos modos diferentes: modo de


subproceso y handler mode. Estos modos se combinan con los niveles de privilegios
que se conceden a la ejecucin de un programa sobre el acceso a determinados
registros:
- En el nivel de acceso sin privilegios, el cdigo ejecutado no puede tener acceso
a todas las instrucciones (las instrucciones especficas para el acceso de registros
especiales quedan excluidos). Generalmente no tienen acceso a todas las funciones
dentro del sistema (Nested Vector Interrupt Controller [NVIC], el sistema
temporizador, etc.). La preocupacin es simplemente para evitar tener cdigo que, por
la mala gestin de un puntero, por ejemplo, sera perjudicial para el comportamiento
global del procesador y perturbar gravemente el funcionamiento de la aplicacin.
16 Assembly Language Programming The Core of Cortex-M3 16

- En el otro extremo del espectro, en el nivel privilegiado, todas estas limitaciones


se eleva.
- Modo de subproceso se corresponde con el modo predeterminado en el sentido de
que es el modo en el que el procesador toma despus del restablecimiento. Es el modo
normal para la ejecucin de aplicaciones. De este modo, tanto los niveles de privilegio
son posibles.
- El procesador pasa a modo de controlador tras una excepcin. Cuando se ha
terminado de procesar las instrucciones de esta excepcin, la ltima instruccin permite
un retorno a la ejecucin normal y provoca el retorno a modo de subproceso. En este
modo, el cdigo siempre tiene acceso a nivel privilegiado.

Paso entre estos tres tipos de funcionamiento puede describirse mediante una
mquina de estado, vase la figura 2.1 [07] YIU. Despus se restablece, el procesador
est en modo de subproceso con privilegio. Estableciendo el bit menos significativo
(LSB) del control de registro, es posible cambiar a modo sin privilegios (tambin
llamado modo de usuario en la documentacin del brazo) mediante software. En modo
sin privilegios, el usuario no puede acceder al control de registro, de modo que es
imposible volver al modo privilegiado. Justo despus del lanzamiento de una
excepcin (vase el captulo 8) el procesador pasa a modo de identificador, que
necesariamente ha de privilegio. Una vez que la excepcin ha sido procesado, el
procesador vuelve a su modo anterior. Si, durante la tramitacin de la excepcin, el LSB
de control de registro se modifica, entonces el procesador puede volver al modo
contrario al que estaba en vigor antes del lanzamiento. La nica manera de cambiar
a modo de hilos sin privilegios, en contraposicin al modo de subproceso privilegiado,
est pasando por una excepcin que se expresa por pasar a modo de controlador.

Este nivel de proteccin puede parecer algo minimalista. Es un poco como el


bloqueo/desbloqueo de su telfono mvil: se necesita una combinacin de teclas
(conocida por todos) para lograr. Evidentemente, no es til para prevenir el robo, pero
es til cuando el telfono est en el fondo de un bolsillo.

Este tipo de seguridad slo puede desarrollarse dentro de una arquitectura de


software global que comprende un sistema operativo. En un bastante simplista pero
finalmente bastante realista, es posible imaginar que el sistema operativo (SO) tiene
privilegios de acceso completo. Puede, por tanto, iniciar tareas de rosca sin
privilegios , de modo que pudiera garantizar un nivel inicial de seguridad. Un segundo
nivel de privilegio se refiere a las funciones de la unidad de proteccin de memoria el
bloque mencionado anteriormente. Cada tarea slo puede acceder a las regiones de
memoria asignada por el sistema operativo.

Un elemento complementario debe ser tenida en cuenta para comprender el


funcionamiento del Cortex-M3. Se trata del estado interno del procesador, que puede
ser tanto en el pulgar o estado de depuracin.
17 Assembly Language Programming The Core of Cortex-M3 17

El trmino pulgar se refiere al conjunto de instrucciones del procesador (vase el


captulo 5), donde el estado asociado (pulgar) corresponde al estado normal de
funcionamiento. Los resultados de estado de depuracin desde un interruptor a modo
de desarrollo. El ndice de ejecucin de un programa no siguen las mismas reglas
(punto de parada, punto de observacin, etc.). De este modo, por lo que
es comprensible que se traduce en un estado en particular. Como cualquier evento en
los mecanismos internos de un procesador, el cambio de un estado a otro es reflejado
(y/o causado) cambiando los valores de uno o ms bits. En este caso se trata de
dos bits (C_DEBUGEN Y C_HALT) situado en el Depurar detener el control
y registro de estado (DHCSR).

REMARK 2.1.- El dominio de las distintas opciones de funcionamiento no es un


prerrequisito para escribir sus primeros programas en lenguaje ensamblador. Las
anteriores explicaciones breves estn all slo para ayudarle a desarrollar las
capacidades del procesador. Tambin estn para ayudarle a comprender que la
observacin del "paso a paso" la ejecucin del programa provienen de la explotacin
de los recursos de procesador especfico mediante el desarrollo de software.

Figura 2.1. Los modos y los


privilegios

2.2. Registra

La primera cosa que debe ser advertido acerca de un procesador es que est
compuesto de varios registros. Este es, sin duda, el enfoque ms pragmtico en la
medida en que las arquitecturas modernas, tales como los de Cortex-M3, se
denomina tipo de almacn de carga
18 Assembly Language Programming The Core of Cortex-M3 18

Las arquitecturas. Esto significa que los programas inicialmente la transferencia de


datos desde la memoria a los registros y realiza operaciones en estos registros en un
segundo paso. Por ltimo, y cuando sea necesario, existe la transferencia de los
resultados de la memoria.

En primer lugar , debemos definir qu es un registro. Un registro, en el sentido


primario, corresponde a la ubicacin en la memoria interna (en el sentido de una serie
de bits accesible en paralelo) de un procesador. Sin embargo, deberamos ajustar esta
definicin por la sencilla razn de que, en el caso de un controlador , aunque hay
memoria interna (20 KB de RAM esttica en el caso de una norma STM32, y eso sin
tomar en cuenta la memoria Flash), esta memoria interna no conforman un conjunto
de registros. Igualmente inexacta definicin sera pensar en un registro como una
ubicacin de memoria que no toma parte en la asignacin de memoria. En efecto, todos
los perifricos de un controlador puede ser programado por medio de los valores que son
dadas por los registros; no tienen menos direcciones fsicas que el procesador puede
acceder a cualquier otro espacio de memoria. El uso generalizado del trmino
"registro" de la arquitectura informtica significa que a menudo este trmino engloba
de una manera bastante vaga, todos los espacios de memoria cuyo contenido afecta
directamente el funcionamiento del procesador. En esta seccin, slo podremos
examinar los registros del ncleo Cortex-M3. Su principal caracterstica es que son
accesibles por el conjunto de instrucciones sin presentar una solicitud para el bus de
datos. El opcode (que est vinculada a la codificacin de la instruccin de ser
ejecutado) de una instruccin para manipular el contenido de un registro debe
contener, por lo tanto, la informacin del registro para ser contactado. La ejecucin
de una instruccin puede causar la modificacin de uno o ms de estos registros sin
necesidad de activar el bus de datos.

Conrtex-M3 tiene 17 registros iniciales, todos obviamente 32 bits:


- R0 a R12: 13 registros de uso general.
- R13: un registro del puntero de la pila, tambin
llamado SP, PSP (SP_process) o MSP (SP_principal);
- R14: enlace registrar (LR).
- R15: contador ordinal o PC (puntero de programa);
- xPSR: un registro estatal (Program Status Register, la x puede ser una de
Aplicacin, I para interrumpir o e para su ejecucin) que es extraamente nunca
llam R16.

A estos 17 registros debemos aadir tres registros especiales (PRIMASK,


FAULTMASK y BASEPRI), que se utilizan para el control de excepciones (vase el
captulo 8). El siglo que podemos aadir a esta lista es el control de registro, que ya ha
sido mencionado por su papel en los niveles de privilegio, pero tambin un nivel del
puntero de pila R13.
19 Assembly Language Programming The Core of Cortex-M3 19

2.2.1. Los registros R0 a


R12

Estos 13 se utilizan registros, como veremos en el pasaje de revisar el conjunto de


instrucciones, como un contenedor para almacenar los operandos de una instruccin y
recibir los resultados de estas operaciones. El brazo se distingue entre los ocho
primeros registros R0 a R7 (baja registra) y los cuatro siguientes (R8 a R12, la alta
registra). Los altos registros de empleo tienen restricciones con respecto a
determinadas instrucciones. El programador prudente principalmente utilizar los ocho
primeros registros para que no tengan que administrar estas restricciones.

REMARK 2.2.- Estos registros generales, contrariamente a otras arquitecturas, slo son
accesibles en paquetes de 32 bits. Los registros, por tanto, no se puede dividir en dos
la mitad- palabras o cuatro bytes. Si su aplicacin se ocupa de bytes (cadenas de
caracteres para ser ms precisos), por ejemplo, los 24 bits ponderada ms alta
se encuentra a 0 para que su funcionamiento sea sensato.

2.2.2. El registro R13, tambin conocida


como SP

R13 es el registro SP. Como su nombre sugiere, los puntos (es decir, contiene la
direccin de una ubicacin de memoria) a un lugar que corresponde a la ubicacin
actual de la pila del sistema. Esta idea de una pila se explicar con ms detalle ms
adelante (vase la seccin
6.5.6), pero por ahora solamente tendremos que considerarla como una zona de
amortiguamiento donde el programa en ejecucin puede almacenar temporalmente
los datos. En el caso de Cortex-M3, esta zona de almacenamiento se duplica, y por lo
tanto el registro SP viene en dos versiones: PSP (SP_Process) o MSP
(SP_principal). Es importante sealar que, en cualquier momento dado, slo uno de
los dos paquetes es visible para el procesador. As que cuando se escribe a la pila como
en el siguiente ejemplo:

EJEMPLO 2.1.- guardar un


registro

Empuje R14 PC Guardar ;


; MSP o PSP???

La escritura se realiza a la zona visible. En trminos de esta visibilidad, podemos


aceptar que, a modo de controlador, el puntero siempre actual MSP. En el modo de
subproceso, incluso si puede ser modificado con el software, el actual puntero es PSP.
As, sin particular manipulacin, el acceso a la pila del sistema ser a travs de PSP
durante el curso normal del programa, pero cuando hay una excepcin a la gestin de la
pila est sujeto a MSP. Esta divisin se induce una mayor fiabilidad en el
funcionamiento del controlador y mayor velocidad durante los cambios de contexto
(no hay que olvidar que el
20 Assembly Language Programming The Core of Cortex-M3 20

Los perifricos se comunican con el Cortex-M3 a travs de interrupciones y as una


excepcin no es excepcional, etc.).

Figura 2.2. Doble sistema de


pila

2.2.3. El registro R14, tambin conocido como LR

A lo largo de este registro, existen indicios de la estructura del programa, que sern
discutidos en el Captulo 7. Nos permiten descubrir, por ejemplo, 2.2, uno de los
mecanismos fundamentales: saltar a una subrutina.

En este ejemplo, el programador ha escrito dos procedimientos (que es el trmino


que se utiliza para el concepto de una subrutina): principales y MyFirst.
El procedimiento principal no hace nada pero llame MyFirst, que por s mismo no
hace nada (el NOP (No Operation) instruccin no tiene ningn efecto ms all de la
utilizacin de un ciclo de mquina para funcionar). Cuando el procesador alcanza
la rama con Link (BL), se utiliza la instruccin LR para almacenar la siguiente
direccin, donde luego modifica el puntero de instruccin y la direccin de la rutina.
En forma simtrica, en la rutina MyFirst con la sucursal y Exchange (BX) instruccin
cambiar el contenido del puntero de instruccin con el valor contenido en el LR y as
volver a donde comenz a continuar procesando la
21 Assembly Language Programming The Core of Cortex-M3 21

Programa de llamadas. Cabe sealar que, a pesar de la implicacin, el smbolo no es


intercambiado sino simplemente copiarse.

EJEMPLO 2.2.- La utilidad del enlace registrar LR

Principales PROC
Aqu BL MyFirst ; Saltar a MyFirst
...
ENDP
....
MyFirst PRO
C
NOP ; ninguna operacin.
BX LR ; volver al programa llamante
ENDP

Figura 2.3. Llamar a la subrutina (uso de la


LR)

2.2.4. El R15 o PC Registro

Este registro puede ser llamado "el puntero de instruccin", "el contador ordinal"
o "el contador de programa (PC)", pero tiene un papel nico: contiene la direccin de
memoria donde la siguiente instruccin a ser ejecutada es almacenada. El LSB de este
registro es (normalmente) en 0, suponiendo que las instrucciones se codifican en 16
bits (pulgar) o
32 bits (pulgar2), de modo que ocupen al menos dos direcciones consecutivas. Durante el
22 Assembly Language Programming The Core of Cortex-M3 22

Ejecucin de una secuencia de cdigo, el puntero pc incrementar automticamente en


s (generalmente dos por dos) para luego punto y recuperar el resto del cdigo. El
trmino contador ordinal podra implicar que su funcionamiento est limitado a esta
simple incremento. Esto no es as, y las cosas se complican rpidamente,
especialmente cuando hay una ruptura en la secuencia (en el caso del ejemplo 2.2,
donde la llamada a una subrutina provoc una discontinuidad en el resto del cdigo
almacenado direcciones). En este caso, PC tendra un valor que no era un simple
incremento de su valor inicial.

La gestin de este puntero est intrnsecamente vinculado a la estructura de este


gasoducto Reduced Instruction Set Computer (arquitectura RISC). Esta tcnica
permite la introduccin de una forma de paralelismo en el trabajo del procesador. En
cada momento, varias instrucciones se procesan simultneamente, cada uno en un
nivel diferente. Tres pasos sucesivos son necesarios para una instruccin para ser
llevado a cabo completamente:
- La fase de Fetch: recuperacin de la instruccin desde la memoria. Esta es la etapa
donde PC juega su parte.
- La fase de decodificacin: la instruccin es un valor codificado en su memoria
( opcode), el cual requiere de descodificacin para prepararlo para su ejecucin (por
ejemplo, recuperacin de datos).
- La fase de ejecucin: la ejecucin de la instruccin descodificada y la escritura
posterior de los resultados si es necesario.

En estas tres etapas (que son clsicas en una estructura de canalizacin) una
primera unidad upstream deben agregarse: la unidad de PreFetch. Esta unidad (que es
parte de la experiencia del brazo) existe esencialmente para predecir lo que suceder
durante la secuencia de saltos y a prepararse para recuperar la siguiente instruccin
por "buffering" sobre seis instrucciones por adelantado. Esta prctica optimiza la
velocidad del procesador.

Esta visin simplificada del oleoducto etapas deliberadamente oculta su


complejidad. Nuevamente, en lnea con los objetivos de este libro, este nivel de
comprensin es suficiente para escribir programas en lenguaje ensamblador. Los
lectores interesados pueden buscar en la documentacin del brazo para encontrar
todas las explicaciones necesarias para ir ms all.

2.2.5. La xPSR
registrarse

Este registro contiene informacin sobre el "Estado" o el "estado" del procesador.


Contiene informacin importante, una especie de informe corto - acerca de lo que ha
sucedido en el procesador. Est disponible en tres versiones, aunque es slo un
registro. La distribucin de los bits significativos, como se muestra en la Figura 2.4,
es tal que no hay interseccin, por lo que es posible que lo dividen en tres
subconjuntos independientes:
23 Assembly Language Programming The Core of Cortex-M3 23

- APSR, con el significado de una aplicacin: este registro contiene las banderas
del procesador. Estos cinco bits son esenciales para el uso de operaciones
condicionales, pues las condiciones exclusivamente expresarse como una combinacin
lgica de estos indicadores. La actualizacin de estos es llevada a cabo por la mayora
de las instrucciones, siempre que el ndice S est especificado en el nombre simblico
de la instruccin. Estas banderas son:
- Indicador C (llevar): representa la "transportar" durante el clculo de las
cantidades fsicas (unsigned). Si C=1 y, a continuacin, hubo un desbordamiento en la
representacin no firmados durante la instruccin anterior, lo que demuestra que el
resultado unsigned es parcialmente falsa. El conocimiento de este bit permite trabajar
mucho ms precisas.
- indicador Z (cero): tiene un valor de 1 si el resultado es cero.
- El indicador N (negativo): copia el bit ms significativo del resultado. Si el
valor est firmado, siendo N 1, por lo tanto, indica un resultado negativo.
- Indicador V (oVerflow): si este tiene un valor de 1, se ha producido un
desbordamiento o subdesbordamiento de representacin firmado. firmado el resultado
es false.
- Indicador Q (indicador de saturacin pegajoso): slo tiene sentido para las dos
instrucciones de saturacin especfico USAT y SSAT: el bit se establece a 1 si estas
instrucciones han saturado el registro utilizado.

- IPSR, con el significado I : interrupcin en esta configuracin, esto se refiere a


los nueve LSBs conteniendo informacin. Estos 9 bits componen el nmero de
excepcin o rutina de servicio de interrupcin (ISR) que ser lanzada. Por ejemplo,
cuando el ISR tiene un valor de 2, que corresponde al lanzamiento de un no ocultable
Interrupt (interrupcin NMI); si tiene un valor de 5, entonces se ha producido un
problema de acceso a la memoria.
- EPSR, con el significado e ejecucin: este registro almacena tres fragmentos de
informacin diferenciados:
- los 24 bits (T) para indicar si est en estado de pulgar - es decir, si se est
usando el conjunto de instrucciones del pulgar. Como esto siempre es el caso, este bit
est siempre a 1. Podramos cuestionar la utilidad de esta informacin. Como
cuestin de hecho, es intil en el caso de Cortex-M3, pero en otras arquitecturas este
bit puede ser 0 para mostrar que el procesador est utilizando el conjunto de brazo y
no pulgar;
- utiliza campos de bits [10-15] y [25-26] para almacenar dos piezas de
informacin superpuesta (los dos usos son mutuamente excluyentes): ICI o ;
- Para ICI, esta es la informacin que se almacena al leer/escribir mltiples (el
procesador lee/escribe varios registros generales sucesivamente, pero slo utiliza una
instruccin) se interrumpe. Al volver de la interrupcin, el procesador puede reanudar
sus mltiples accesos desde donde estaba antes.
24 Assembly Language Programming The Core of Cortex-M3 24

- para TI, existe una determinada instruccin If/Then 1 en el conjunto de


instrucciones. Los bits en la ejecucin de esta instruccin contendr el nmero (entre
1 y 3) de instrucciones que sern incluidos en un bloque If/Then y una codificacin
de las condiciones para su ejecucin.

La EPSR tiene, por tanto, utilizacin relativa para el programador. Adems,


cuando sabemos que no se puede cambiar, podemos permitirnos olvidar su existencia
en la elaboracin de nuestro cdigo.

En la figura 2.4. La xPSR


registrarse

Desde el punto de vista del lenguaje ensamblador, el siguiente ejemplo muestra


que es posible acceder a las tres entidades por separado o para acceder a la totalidad.
Cabe sealar que esta lectura slo puede hacerse a travs de una
determinada seora (Mover al registro de instruccin especial). Simtricamente, la
escritura de estos registros requiere el uso de un determinado MSR (Mover a registro
especial) instruccin.

EJEMPLO 2.3.- carga del registro de estado

La Recopa la Sra. R4, parte APSR APSR ; carga en R4


La Sra. R5, IPSR ; carga IPSR parte en R5
La Sra. R6, EPSR ; carga EPSR parte en R6
La Sra. R7, PSR ; carga todo el PSR registrarse en R5

1 Afortunadamente, esta instruccin no es la nica forma de escribir "si si no Entonces"


estructura en lenguaje ensamblador. Un enfoque ms sistemtico, por salto condicional, permite
la construccin de todo tipo de estructuras algortmicas (vase la seccin 6.2).
Captulo 3

La correcta utilizacin de las directrices


de la Asamblea

Como cualquier lenguaje, el aspecto sintctico de un anuncio es de crucial


importancia para que el compilador (en el caso de nivel superior) o las estructuras de
lenguaje ensamblador (para listas escritas en lenguaje ensamblador) comprende el
resto de los caracteres que se van a leer y que componen el programa. Si tenemos en
cuenta los ejemplos anteriores, un ensamblador tendra problemas para generar el
cdigo ejecutable correspondiente: carece de un montn de informacin. Slo unas
pocas instrucciones, sin ningn contexto, fueron transcritas en los ejemplos que
anteriormente se han presentado. Donde es el punto de entrada del cdigo, donde
funciona el programa final, donde est el cdigo situado en la memoria, cules son las
constantes o variables?

Este captulo pretende definir este contexto mediante la descripcin de las


directrices de la Asamblea.

3.1. El concepto de la directiva

Una directiva de ensamblado es un fragmento de informacin que aparece palabra


por palabra en el listado y que es suministrada por el ensamblador para dar las reglas
de construccin del ejecutable. Estas lneas en el archivo de origen, aunque una parte
integrante de la lista y es necesario para su coherencia, no corresponden directamente
a cualquier lnea de cdigo. Estas piezas de informacin, por lo tanto, no aparecern
durante el desensamblado del cdigo y tambin estar ausente si un hacker intenta
realizar ingeniera inversa. El desmontaje es un proceso que consiste en convertir el
cdigo (es decir, la coleccin de palabras ledas en memoria) en los smbolos
correspondientes y, si es necesario, los operandos (numrico o registrarse). La
codificacin de una instruccin es biunvoca, no hay ningn problema en volver a
transcribir un cdigo extrado de la memoria en conjunto primitivo
26 Assembly Language Programming The Proper use of Assembly Directives 26

Idioma. La capa simblica no da una comprensin de lo que est programado - seguir


siendo bastante incomprensible! Por ejemplo, el desensamblado del cdigo de
ejemplo 2.2 ofrece las siguientes lneas:

EJEMPLO 3.1.- ejemplo de desmontaje

0x080001A0 BL.W 0x080001A8

0x080001A4 B 0x080001A4

0x080001A6 NOP

0x080001A8 NOP

0x080001AA BX LR

En este ejemplo, la primera columna indica el valor de la direccin donde se


almacena la instruccin. Por echndole un vistazo a estas direcciones, podemos ver
que una instruccin es codificada en dos bytes (cdigo de tipo de pulgar) o cuatro
bytes (pulgar-2 Tipo de cdigo). La segunda columna corresponde a la decodificacin
de la instruccin de lectura y la tercera, a la que acompaa los posibles argumentos.

3.1.1. Convenciones tipogrficas y uso de smbolos

En el siguiente texto, las siguientes convenciones tipogrficas han sido aprobados:


- slim itlicas denotan una secuencia de caracteres que debe elegir.
- las palabras escritas en maysculas son obligatorios. Nos escriben en maysculas
para hacerlos evidentes, pero tambin pueden ser escritos en minsculas.
- negrita cursiva indica un campo donde el valor es ser elegidos a partir de una lista.
- las zonas no escrito entre corchetes { } son obligatorios. Los dems campos son
opcionales, pero nunca podemos escribir los corchetes.

Con el fin de escribir sus programas, necesitar definir los smbolos (una constante,
una etiqueta para identificar una lnea de cdigo, una variable, etc.). Tambin
podemos utilizar el trmino identificador para estos nombres definidos por el usuario.
Ser siempre un smbolo asociado a un valor numrico por el ensamblador y el linker:
De la misma manera que las directivas definidas anteriormente, un smbolo nunca
ser incluido explcitamente en el cdigo final. La legibilidad de los programas, por
naturaleza muy baja en lenguaje ensamblador, es, por tanto, directamente vinculada
a la semntica de los smbolos. Por lo tanto, es mejor ser generoso con los personajes
para hacerla ms explcita. Desde un punto de vista sintctico, un smbolo tambin
deben respetar las siguientes reglas para ser aceptados por el ensamblador:
27 Assembly Language Programming The Proper use of Assembly Directives 27

- el nombre de un smbolo debe ser nico dentro de un mdulo determinado;


- Los personajes pueden ser maysculas o minsculas, nmeros o "subraya". El
ensamblador es sensible a las maysculas y minsculas.
- a priori, no hay longitud mxima;
- el primer carcter no puede ser un nmero.
- las palabras clave (mnemnicos, directivas, etc.) de la lengua estn reservados.
- si resulta necesario utilizar una paleta de caracteres ms importantes (con el fin
de mezclar el cdigo con un compilador, por ejemplo), es posible hacer esto por los
alrededores con el smbolo | (estos no se convierten en parte del smbolo). Por
ejemplo,.text || es un smbolo vlido y el ensamblador memorizar (en su tabla de
smbolos) como .text.

3.2. Estructura de un
programa

Escribir un programa en lenguaje ensamblador, en su forma ms simple, implica


que el usuario puede, en un archivo de cdigo fuente (que es simplemente un archivo
de texto y, por lo tanto, una simple serie de caracteres ASCII):
- definir la secuencia de instrucciones del cdigo, de manera que el ensamblador
sern capaces de traducirlos en lenguaje de mquina. Esta secuencia, una vez
montado y Cortex-M3 Estructura de Harvard, se almacenarn en la memoria de
cdigo;
- declarar los datos que va a utilizar, asignndole un valor constante o
inicial, si es necesario. Esto permite que el ensamblador para dar rdenes a la necesaria
reserva espacio en memoria, por lo que la inicializacin est predestinada para llenar
la memoria de datos, cuando proceda.

REMARK 3.1.- una tercera entidad es necesaria para la correcta ejecucin de un


programa: la pila del sistema. Esto no es fijo en el tamao o la ubicacin de la
memoria. Esto implica que en algn lugar de la lista hay una reserva para esta rea
especfica y al menos una instruccin para la inicializacin del puntero de pila (SP),
responsable de su gestin. En el uso de herramientas de desarrollo existentes, esta
fase a menudo se incluye en un archivo (escrito en lenguaje ensamblador) que
contiene una serie de inicializaciones. De hecho,
La hosting controller Cortex-M3 debe someterse tambin a una serie de operaciones
de configuracin justo despus de un restablecimiento; la inicializacin de la pila en
este archivo es, por consiguiente, no aberrante. El Programador avanzado, sin
embargo, deber comprobar que el tamao predefinido de la pila del sistema no est
bajo o sobre-tamao relativo a su aplicacin.
28 Assembly Language Programming The Proper use of Assembly Directives 28

3.2.1. El rea secciones

Un programa en lenguaje ensamblador debe tener por lo menos dos partes, al que
nos referiremos como secciones, que deben definirse en el listado por el rea directiva:
- una seccin de cdigo que contiene la lista de instrucciones.
- una seccin de datos donde podemos encontrar la descripcin de los datos
(nombre, tamao, valor inicial).

REMARK 3.2.- a diferencia de lenguajes de alto nivel donde la declaracin de


variables, que pueden ser ms o menos mezclado con instrucciones, el lenguaje
ensamblador requiere una clara separacin.

Desde el punto de vista del ensamblador, una seccin es una zona contigua de
memoria en la cual todos los elementos son de la misma naturaleza lgico
(instrucciones, datos y pila).

El programador utiliza el rea directiva para comunicarse con el ensamblador para


mostrar el comienzo de una seccin. La seccin termina naturalmente en el comienzo
de otra seccin, as que no hay ningn marcador especfico para el final de una seccin.

El cuerpo de una seccin se compone de las instrucciones para el elemento


analtico o de diversos lugar reservas (si no inicializado) para la seccin de datos.

La definicin general de la sintaxis de una seccin, ya que debe ser construido en


un archivo de cdigo fuente, es:

Nombre_de_seccin REA ,tipo { } { ,attr }

el cuerpo de la seccin:
Definiciones de los datos ...
o instrucciones, segn el caso

As que vamos a explicar los cuatro campos:


- rea: la propia directiva.
- Seccin_Name: el nombre que le han dado a la seccin de conformidad con las
reglas enunciadas anteriormente;
- tipo: cdigo o datos: indica el tipo de seccin que se abre;
- un conjunto de opciones no obligatorios. Las principales opciones son:
29 Assembly Language Programming The Proper use of Assembly Directives 29

- readonly o readwrite: indica si la seccin es accesible a slo lectura (el


predeterminado) o secciones de cdigo para leer y escribir (el valor por defecto para
las secciones de datos)
- noinit: indica, por una seccin de datos, que no se ha inicializado o inicializar en
0. Este tipo de seccin slo puede contener reservas de memoria spera o reservas
para los datos inicializados en 0, y
- align = n con un valor entre 0 y 31. Esta opcin indica cmo la seccin debera
colocarse en la memoria. La seccin se alinear con 2n modulo electrnico, o en otros
trminos significa que los n bits menos significativos de la primera direccin de la
seccin sera de 0.

Hay otras opciones que, si necesitan ser colocados en su lugar, mostrar que han
alcanzado un nivel de especializacin ms all del alcance de este libro.

En un programa, una seccin determinada puede abrirse y cerrarse varias veces.


Tambin es posible que podamos abrir diferentes secciones de cdigo o datos que son
distintos entre s. Por ltimo, todas estas diversas partes se combinan automticamente.
Ese es el papel del vinculador, por lo que deberan tener en cuenta las diversas
limitaciones para que pueda asignar direcciones de memoria para cada seccin del
proyecto constituyente.

3.3. Una seccin de cdigo

Una seccin de cdigo contiene instrucciones en forma simblica. Una instruccin


es escrita en una lnea, de acuerdo con la sintaxis siguiente:

Etiqueta de smbolo { } { }{ expr ,expr }{ ,expr} { ; comentario}

La sintaxis de todo el lenguaje ensamblador es riguroso. A lo sumo, podemos


colocar una instruccin en una lnea. Tambin es permitido tener lneas sin una
instruccin que contenga una etiqueta, un comentario o incluso nada en absoluto (en
el espacio de la lista a fin de hacerlo ms legible). Por ltimo, tenga en cuenta que la
etiqueta debe colocarse siempre en la primera columna de la lnea.

3.3.1. Etiquetas

Una etiqueta es un smbolo de su eleccin que siempre est construido de acuerdo


con las mismas reglas. La etiqueta sirve como un marcador o un identificador, por la
instruccin (o los datos). Nos permite ir a esa instruccin durante la ejecucin por
medio de un salto (o sucursal).
30 Assembly Language Programming The Proper use of Assembly Directives 30

A continuacin se muestra un ejemplo de un fragmento de programa de inters


algortmico limitado, pero que contiene un bucle y, consecuentemente, una etiqueta.
Con cada bucle, el programa incrementa el registro R3 por un valor contenido en R4.
El nmero de bucles realizadas tambin calcula un incremento unitario (en este caso)
en el registro R0. El bucle se lleva a cabo en la medida en que no se exceda la
capacidad (mientras el pabelln C del registro xPSR permanece en 0).

EJEMPLO 3.2.- Saltar a una etiqueta

MOV R0,#0 ; la inicializacin del


contador
MOV R3, #4 ; Valor inicial

MOV R4, #35 ; el incremento

Agregar Turnal R0,#1 ; el incremento del


contador de bucle
Agrega R3,R4 ; el incremento del valor

BCC Turnal ; rama condicional

Inf B Inf

El smbolo # indica un direccionamiento inmediato, es decir, precede a una


constante para uso como lo es (en este caso para cargar el registro). La ltima
instruccin (BCC) es un salto condicional. La Subdivisin B significa una solicitud y
el sufijo CC significa claro llevar. Por lo tanto, el procesador slo realiza el salto si la
operacin anterior (adems con asignacin de bandera) no causa un rebasamiento y la
conmutacin del pabelln C a 1. El punto de encuentro (Turnal) es el operando que
sigue a la instruccin de CCO y corresponde a la etiqueta colocada unas lneas ms.

Una versin de un salto sin condiciones est presente en la ltima lnea de este
ejemplo. La instruccin salta a la etiqueta que marca esa misma instruccin. Por lo
tanto corresponde a un bucle infinito.

Cuando colocamos una etiqueta en una lnea vaca, sirve para marcar la primera
instruccin (o trozo de datum) que le sigue. Para el ensamblador, las etiquetas son
equivalentes a las direcciones. El valor numrico de una etiqueta es el valor de la
direccin que representa. Esta etiqueta tambin puede ser la direccin de una
instruccin o una hoja de datos.

REMARK 3.3.- En todos los lenguajes ensambladores, el concepto de etiqueta o


constante ha sido ampliado: es posible asignar un valor a una etiqueta gracias a los
iguales (EQU) la directiva, de la que hablaremos en el Captulo 4. Es el equivalente
de un #define en lenguaje C. La etiqueta tiene el significado de un tamao numrico
escrito en forma simblica, que no es necesariamente una direccin.
31 Assembly Language Programming The Proper use of Assembly Directives 31

3.3.2. Nemotcnica

Utilizamos mnemotcnico para significar el nombre simblico de una instruccin.


Este nombre se establece y la serie de mnemnicos conforma el conjunto de
instrucciones.

En el mundo, ya que el brazo de ARMV4 versin de la arquitectura, ha habido dos


conjuntos de instrucciones diferentes: el conjunto de brazo (codificado en 32 bits) y el
pulgar (codificado en 16 bits). El tamao para la codificacin con el pulgar fijado sea
menor, este conjunto ofrece menos posibilidades que en el conjunto de todo el brazo.
La ventaja que se puede sacar de esta compresin es un cdigo ms compacto. Para
muchos procesadores ARM, existe la opcin de que stos funcionen en el pulgar o
modo de brazo, de acuerdo a las necesidades y limitaciones del proyecto
correspondiente.

Desde la versin de arquitectura ARMV6, ARM ha introducido un segundo


sutileza introduciendo un dedo pulgar-2 versin para el conjunto de instrucciones. En
esta segunda versin del pulgar denominacin, el conjunto de 16 bits se ampli con
algunas instrucciones de 32 bits
La densidad y el rendimiento de la cosechadora, como se muestra en la Figura 3.1 1.

Figura 3.1. Las actuaciones y la densidad de los diferentes conjuntos de instrucciones

Cortex-M3 utiliza exclusivamente el pulgar-2 juego. Por lo tanto, es imposible


cambiar a modo de brazo (esta es la razn por la que el bit T en la ejecucin del
Programa Registro de Estado [EPSR] (vase la seccin 2.3.5) siempre se establece en
1).

1 Este diagrama es extrado del brazo documentos comerciales y, por lo tanto, debe
entenderse como tal.
32 Assembly Language Programming The Proper use of Assembly Directives 32

El pulgar-2 juego comprende 114 diferentes procedimientos mnemotcnicos


(excluyendo la comunicacin instrucciones con un coprocesador potenciales). Una
clasificacin rpida nos permite escoger:
- 8 mnemnicos para sucursales de instrucciones;
- 17 para instrucciones aritmticas bsicas (adicin, comparacin, etc.);
- 9 para desplazamiento lgico;
- 9 para la multiplicacin y la divisin.
- 2 para las instrucciones de saturacin.
- 4 para el cambio de instrucciones de formato (conmutacin de ocho a 16 bits, por
ejemplo);
- 10 para determinadas instrucciones aritmticas;
XPSR - 2 para registrar recuperacin;
- 24 unitario para las operaciones de la memoria de lectura/escritura.
- 12 para varias operaciones de lectura/escritura de memoria;
- 17 para diversas instrucciones (ESPERAR, NOP, etc.).

REMARK 3.4.- Se debe tener cuidado de no cometer un error con respecto a la


complejidad de las operaciones. Todas estas son operaciones que slo manejar
enteros (signed o unsigned). Los novatos no deben sorprenderse de no encontrar, con
estos procesadores, capacidades para el manejo de los nmeros de punto flotante, por
ejemplo. De igual manera, para todo lo relacionado con la estructura algortmica o
gestin de estructuras de datos avanzadas, ser necesario romper incluso la ms
pequea de las operaciones a fin de adaptarse al lenguaje ensamblador.

3.3.3. Operando
s

Ley de instrucciones y/o con los operandos proporcionados. Una instruccin


puede, segn el caso, de cero a cuatro operandos, separados por comas. Cada uno de
los operandos es escrito en la forma de una expresin expr que es evaluado por el
ensamblador. Generalmente, las instrucciones aritmticas y lgicas tomar dos o tres
operandos. En el caso de cuatro operandos es relativamente rara en este conjunto de
instrucciones. En el caso del pulgar-2 juego, aparte de las instrucciones de lectura y
escritura, los operandos son de dos tipos: valores inmediatos o registros. Instrucciones
para lectura/escritura, el primer operando ser un registro y el segundo debe ser una
direccin de memoria. Existen diversas tcnicas para especificar estas direcciones;
estas tcnicas corresponden a la idea de que el modo de direccionamiento, que se
explica ms adelante (vase la seccin 4.3). Por lo tanto, es necesario tener en cuenta
que, debido a la carga/almacenamiento de arquitectura Cortex-M3, esta direccin
33 Assembly Language Programming The Proper use of Assembly Directives 33

Siempre se almacenan en un registro. Todos los accesos de memoria requerir la


previa recuperacin de la direccin de la meta a ser alcanzada en un registro.

Nos permiten modificar el programa anterior para que el valor inicial corresponde
al contenido de un byte denominado Bytinit. Como se sabe ahora, vamos a agregar la
declaracin de secciones a este programa.

EJEMPLO 3.3.- La memoria operando

;****************************************************************

; Seccin de datos

;****************************************************************

rea MyData, datos, align = 2

El DCB Bytinit 0x124

;****************************************************************

; seccin de cdigo

;****************************************************************

MyCode, cdigo de rea, readonly, align = 3

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

; subrutina Main

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Principales PROC

LDR, R6=Bytinit ; carga direccin

MOV R0,#0 ; la inicializacin del contador

LDRB R3, [R6] ; carga del valor inicial

MOV R4, #35 ; el incremento

Agregar Turnal R0,#1 ; el incremento del contador de


bucle

Agrega R3,R4 ; el incremento del valor

BCC Turnal ; rama condicional

Inf B INF

;*******************************************************************
34 Assembly Language Programming The Proper use of Assembly Directives 34

En este ejemplo (vase la figura 3.2), podemos ver que para modificar R3 con el
valor almacenado en el bloque de memoria denominado Bytinit, es necesario pasar a
travs de un registro adicional (R6). Este cdigo se recupera, en una primera etapa ( ),
la direccin de la variable (LDR, R6=Bytinit,). Luego, en una segunda etapa ( ) con el
"direccionamiento indirecto", CARGA R3 con el valor almacenado (LDRB R3, [R6]).
El registro R6, una vez inicializado, acta como un puntero a la zona de memoria que
se va a leer. Tambin podemos sealar que slo el byte menos significativo est
copiado, como la instruccin LRDB lleva a cabo la transferencia de un solo byte. Por
otra parte, la instruccin se refiere a la totalidad de la R3 registro, a fin de los 24 bits
ms significativos de este registro se establece en cero durante la transferencia. El
contenido final de la R3 de 32 bits registrarse es efectivamente equivalentes a los
nmeros sin signo almacenado en un byte en Bytinit.

REMARK 3.5.- Es importante sealar que la etiqueta Bytinit no es en s misma los


datos. Es simplemente un marcador de datos - su direccin.

Figura 3.2. El uso de un registro como puntero

3.3.4. Comentarios

Un comentario debe comenzar con ; (punto y coma), incluso si no es la nica


cosa en la lnea. Siempre termina el cdigo al final de la lnea. Si queremos escribir
un comentario requiere varias lneas, cada lnea debe comenzar con ; (punto y coma).
Los comentarios pueden colocarse en cualquier parte del programa, siempre que estn
al final de la lnea actual. Vale la pena recordar que un anuncio es ms a menudo leer
que escrito incluso por
35 Assembly Language Programming The Proper use of Assembly Directives 35

Quienes lo escribieron. Por tanto, es especialmente til a la hora de reexaminar el


cdigo escrito varias semanas, meses, aos, etc., antes de hacer comentarios, as que
no dudes en darles!

3.3.5. Procedimi
ento

En el lenguaje ensamblador presentados aqu, todas las instrucciones deben ser


escritos dentro de un procedimiento. Por lo tanto, es normal que la primera lnea tras
la apertura de una seccin parece una lnea donde el nemotcnico es reemplazado
por PROC, como en el ejemplo siguiente.

EJEMPLO 3.4.- La declaracin de un


procedimiento

En el rea de Nueva_Section, cdigo readonly, align = 2

MyFunct PROC

... ; el cuerpo del procedimiento (instrucciones).

...

ENDP

Llamamos a una secuencia de instrucciones de un "procedimiento". Podemos


distinguir desde un subprograma (o subrutina) cuando la ltima instruccin nos
permite volver a un programa de llamadas. Vamos a volver a los detalles de cmo
escribir y usar los procedimientos en la seccin
7.1, pero por ahora centrmonos en lo bsico: la llamada a un
procedimiento.

La forma ms genrica de la llamada es una rama y enlace (BL MyFunct), con el


retorno correspondiente a un re-asignacin del puntero de instruccin por la
instruccin BX LR (habitacin e intercambio), como se muestra en el Ejemplo 2.2.

Como con el lenguaje C, hay un procedimiento principal, el primero en ser lanzado


despus de una secuencia de inicializacin del controlador conocido como
el principal. No es estndar, como en lenguaje C. Es perfectamente posible sustituir la
inicializacin estndar biblioteca con su propia biblioteca, haciendo el trabajo de
inicializacin. Esta nueva biblioteca podra entonces hacer
La llamada al punto de entrada del programa de aplicacin - el punto de entrada cuyo
nombre podra ser elegidos libremente por el programador.

REMARK 3.6.- Es posible sustituir el PROC/ENDP emparejar con la


funcin/ENDFUNC pareja, sabiendo que el idioma no hace distincin entre
procedimiento y funcin, a diferencia de algunos lenguajes de alto nivel.
36 Assembly Language Programming The Proper use of Assembly Directives 36

3.4. La seccin de datos

Un conjunto de directivas nos permite reservar espacio de memoria que ser


utilizada por el programa para almacenar datos. Tambin es posible asignar dicho
espacio un valor inicial, si es necesario. Esta manipulacin parece simple, pero
necesita ser examinada ms detenidamente.

3.4.1. Simple reserva

Esto significa simplemente reservar un espacio de memoria y, opcionalmente, dndole un


nombre.

Etiqueta { } espacio expr

Expr es la cantidad (expresada como un nmero de bytes) de memoria que queremos


asignar. Esta zona se establecer en 0 por defecto.

Las expresiones numricas son las cantidades que se presentan directamente al


ensamblador. En el caso que estamos considerando aqu, es el nmero de bytes que
se reservan, pero ms tarde puede ser un valor inicial, un valor inmediato a ser dada
a un registro, etc. esta cantidad puede expresarse en diferentes bases:
- base decimal: el valor por defecto de la base, como tampoco un prefijo ni sufijo es
necesario;
- base hexadecimal: como en lenguaje C, esta base est seleccionado cuando la
cantidad es el prefijo 0x (por ejemplo, el valor 255 sera 0x00FF). Una alternativa es
usar el &;
- cualquier base (entre 2 y 9): La sintaxis es base_dgitos, donde base es la sede
elegida y los dgitos son los caracteres (de 0 a -1 de base) en representacin de los
caracteres. (por ejemplo en base 5: 5_1213 representa el valor 183 = 1 5 3 + 2 5 2
+ 1 51 + 3
50). Esta posibilidad resulta ser interesante para el binario de base, en el que el
programador puede fcilmente expresar un valor (de un registro, por ejemplo) para
que l o ella sabe los bits para localizar. Por ejemplo, poner los tres y cinco bits de un
byte ponderadas en 1, el programador debe especificar: 2_00101000_101000 = 2 =
0x28 = 40;
- ASCII "base": no es til para aprender la tabla ASCII por corazn. Por los
alrededores de un solo personaje con comillas simples ('), el ensamblador comprender
que debe tener el valor ASCII del carcter como valor de la expresin. Tambin es
posible construir una cadena de caracteres (para crear un mensaje, por ejemplo)
colocndolos dentro de las dobles comillas ("). Ejemplo 3.6 ilustra esta tcnica con la
declaracin y la inicializacin de la variable Cadena.

Tenga en cuenta que esta expresin puede ser un simple clculo literal. Por ejemplo
Espacio LotsOfWords 12*4+3 se reserva 51 bytes. El clculo es obviamente
37 Assembly Language Programming The Proper use of Assembly Directives 37

Realizado por el ensamblador (y por lo tanto el procesador del ordenador host de


desarrollo) al generar el cdigo (y no en cualquier momento por Cortex-M3!). Los
principales operadores aritmticos (+, -, *, /, >> (Mays derecha) << (izquierda
Mays) & (y), | (o), etc.) nos permiten construir estas expresiones literales. El usuario
avanzado encontrar una lista exhaustiva y detallada de los operadores existentes y
su nivel de prioridad (la prioridad relativa), sabiendo que las escuadras estn
permitidos, en la documentacin tcnica DEL BRAZO [10].

3.4.2. Reserva con la inicializacin

Existen diferentes directivas para crear zonas de memoria que contienen valores especficos
(inicializa las variables). A continuacin se muestra una lista con los
argumentos posibles:

Label1 { } { expr relleno,valor,valuesize{} }

Label2 { } DCB expr1 {,expr2}{,expr2}...

Label3 { } DCD{U} expr1 {,expr2}{,expr3}...

{ } DCW label4{U} expr1 {,expr2}{,expr3}...

{ } DCQ label5{U} expr1 {,expr2}{,expr3}...

La reserva para el relleno es la contrapartida de la directiva el espacio sino con el


proceso de inicializacin. Especificamos que queremos reservar expr inicializado bytes
con valor , que est codificada en valuesize bytes. Para que sea totalmente compatible,
el tamao de la reserva (expresin) debe ser un mltiplo del valor de valuesize.

REMARK 3.7.- Todos los valores sin signo pueden almacenarse en un formato ms
grande de lo que es estrictamente necesario para su tamao; slo tiene que aadir 0
delante de la bits tiles. El Ensamblador no puede saber a priori en qu tamao debe
cdigo la informacin.

Las otras cuatro directivas para especificar el tamao de la variable con la ltima
letra de la mnemnica: B = byte, W = media palabra (2 bytes), D = palabra (4 bytes)
y Q = doble palabra (8 bytes). Los datos se alinean por defecto: tipo W datum se inicia
en una direccin (incluso en 0 bit menos significativo), y tipo D y Q son datos sobre
modulo
4 direcciones (los dos bits menos significativos
en 0).

El nmero de reservas, por lo tanto, corresponde a un nmero dado de valores


iniciales. La primera inicializacin es obligatoria. Las siguientes son opcionales. El
siguiente ejemplo utiliza estas directivas diferentes con diferentes bases y varios
38 Assembly Language Programming The Proper use of Assembly Directives 38

Formas de expresiones literales. La figura 3.3 muestra la asignacin de memoria


resultante de este ejemplo, teniendo 0x20000000 como direccin base.

EJEMPLO 3.6.- reservas con la inicializacin

0x24,2 Bytinit DCB_0111

La cadena "Toto", DCB'*',10,13

HalfW DCW 47, 12+3

Palabra DCD 3,0xFFFF * 3

Byte 0DCB xAB >> 2 ; dos turnos derecho

Peligro DCWU 0x1234

Figura 3.3. Mapeo del ejemplo de reservas con la inicializacin

En el ejemplo, se agregan tres bytes de relleno por el ensamblador para permitir la


alineacin correcta de los datos. Un byte se coloc en 0x20000009 porque HalfW fue
colocado incluso a una direccin (0x2000000A) y dos bytes se agregaron en
0x2000000E porque los dos bits menos significativos de la palabra direccin estaban
en 0 (0x20000010). En contraste, la mitad de la palabra peligro se encuentra unaligned
en 0x20000019, ya que la directiva DCWU fue utilizado para crearlo.

La opcin U significa que la alineacin es innecesario, sino que puede ser muy
peligroso! De hecho, el ensamblador alinea sus reservas en un siquiera abordar por
medio de palabras y doblemente incluso (divisible por 4) la direccin de palabras. Sin
embargo, esta alineacin no es estrictamente necesario. Cortex-M3 permite unaligned
accesos a la memoria. Dichos accesos no son en absoluto optimizado, ya que tendr
que hacer dos (lectura o escritura, dependiendo de la direccin de la instruccin) ciclos.
39 Assembly Language Programming The Proper use of Assembly Directives 39

Es principalmente en aras de optimalidad que la alineacin est en vigor en el nivel


de reservas de memoria por el ensamblador. Sin embargo, ARM tiene siempre la
opcin de prohibir unaligned access, fsicamente hablando. Esto se
hace configurando el peso tres bits (UNALIGN_TRAP) en la configuracin de
Control de registro a 1. As colocados, cualquier acceso a una media palabra en una
direccin extraa, o una palabra en una no-doblemente incluso direccin, podra causar
un fallo de uso (vase la seccin 8.2.1.4). Si el procesador est configurado en este
estado, se convierte en indispensable para gestionar rigurosamente (en particular, en
relacin con la alineacin de sus punteros).

3.4.3. Inicializacin de datos: El diablo est en los


detalles

Lo que sucede en la vida de inicializar una variable? En un ciclo de desarrollo


normal, podemos imaginar que esta variable es nacido en la carga del programa en
memoria. El cargador (programa a cargo de la transferencia desde el desarrollo
toolchain al destino que contenga Cortex-M3) escribir el valor inicial prevista para
la direccin de memoria correspondiente a esta variable. Entonces, si la variable es
"variable", que va a cambiar y ya no ser igual a su valor inicial. Supongamos ahora
que el usuario reinicia el destino (RESET). El programa se reiniciar sin pasar por
el paso del cargador. Qu garantiza que el valor inicial ser re-transcrito? A priori, en
lenguaje ensamblador, nada; sin embargo, resulta que en la mayora de los casos
(porque a menudo se empareja con un compilador de C) el ensamblador se ha
anticipado a esto. El mecanismo puesto en marcha se basa en una duplicacin de la
inicializacin de zonas: una primera memoria de acceso aleatorio (RAM) Tipo de
espacio de direcciones para las propias variables y un duplicado en memoria de slo
lectura (ROM)-Tipo (normalmente justo despus del cdigo) que contienen los
valores iniciales. A continuacin es suficiente para tener una rutina a su disposicin
que recupera las tablas de diferentes direcciones de zona y, a continuacin, funciona
una copia de uno sobre el otro. Una ligera adaptacin de este mtodo tambin nos
permite reinicializar las variables en cero. Estas maniobras, aunque muy til, no puede
aparecer de forma muy clara. As, en el caso del brazo-MDK (Kit de desarrollo de
microcontrolador), esto se realiza mediante el uso de una biblioteca dinmica en el
cdigo, lo que se consigue aadiendo un bonito pero sin embargo
ocultar Importar||Lib$$$$armlib Solicitud|| para el encabezado del archivo principal.
Este mecanismo de inicializacin se revisan en detalle en el Captulo 9.

3.5. Es que
todos los?

Obviamente no es. Tambin hay ciertas directivas para el ensamblador que no se


explican completamente en este captulo. Algunas de ellas (EQU, RN y LTORG) se
analizan en el captulo siguiente ya que ocuparse principalmente de la manipulacin
de los datos (y, por lo tanto, operando la administracin). Otros se refieren a la
distribucin (Importar, Exportar) de variables o procedimientos, que es el tema del
Captulo 9. Pero otros no se menciona aqu porque el inters en su uso es algo
limitado (INFO, TTL, etc.).
40 Assembly Language Programming The Proper use of Assembly Directives 40

Los que quedan se enumeran a continuacin. Son ms especficos (en el sentido de


que su uso no es generalmente necesario para producir un ejecutable), pero pueden ser
muy tiles.

3.5.1. Las directivas de administracin de memoria

Alinear {expr}

Cuando el argumento expr debe ser un valor de cualquier potencia de 2 (a partir del 2
de0 a 232). Si expr no es especificado, su valor es de 2. Alinee se utiliza para datos de
posicin (o instrucciones) que siga esta directiva en un modulo expr direccin
alineada. La presente Directiva se inserta ceros (en la zona de datos) o instrucciones
NOP (en la zona de cdigo) con el fin de alinear el cdigo. Su utilidad es evidente
para resolver problemas unalignment memoria potencialmente mortales. El uso de
una alineacin 1 es posible pero no presenta ningn inters. ALIGN puede tomar otros
argumentos opcionales para insertar un desplazamiento adicional la alineacin.

Un ejemplo tpico del uso de esta directiva es que las reservas de espacio de
memoria para hacer una pila de usuario (tambin conocido como un montn). La
reserva se realiza por el espacio de la directiva, que no gestiona la alineacin. Si el
acceso a esta pila se utiliza nicamente para la lectura/escritura de 32 bits, est bien
para colocar la direccin base de la pila en un doblemente incluso valor. Ejemplo 3.7
muestra cmo esta reserva puede hacerse a travs de una alineacin forzada.

EJEMPLO 3.7.- La reservacin para una pila


de usuario

Dim EQU 64

Variable 0 DCB ; reservas no utilizadas


slo para crear
; un unalignment en la
memoria
Alinear 4 ; forzando de alineacin
para
; la prxima reserva

MyStack Espacio 4*Dim ; reserva de Dim palabras

Cumbre_Stack ; la etiqueta en la parte


superior de la pila

Smbolo comn{{,tamao,alineacin}}
41 Assembly Language Programming The Proper use of Assembly Directives 41

Esta directiva nos permite reservar (marcada con el nombre de smbolo) una zona
de memoria comn el tamao (en bytes) y siempre alineados siguiendo la misma
sintaxis que el indicado para el uso de la esfera para la opcin de alineacin. Los
espacios de memoria as creados sern reservadas por el vinculador en una zona
establecida a 0 y agrupados. Esto significa que, en ltimo trmino, el vinculador slo
reservamos una sola zona comunitaria dentro de las cuales la ms importante zona
comn ser incluido. Una de las ventajas de tener esta directiva es optimizar la
administracin de la memoria en importantes proyectos, particularmente para la
asignacin de memoria dinmica en un sistema operativo.

{label}{.DCI expr W}{},expr

Esta directiva nos permite reservar las ubicaciones de memoria con inicializacin
(expresin), como con las directivas DCB, DCD, pero en la zona de cdigo en lugar
de la zona de datos. Por ejemplo, podemos usar esta directiva para crear tablas de salto
para realizar accesos indexado a un conjunto de procedimientos (vase la seccin
6.2.4).

Requerir8} {bool
preservar8 {bool}

Aqu, bool puede tener un valor de VERDADERO o FALSO. La ausencia


de bool sera equivalente a TRUE. Estas dos directivas nos permiten especificar para
el ensamblador que queremos obtener o conservar un mdulo 8, alineacin de la pila
del sistema. Es de poco uso en lenguaje ensamblador. El programador administra su
propio sistema de pilas en la pila, y no tienen que preocuparse por esta alineacin de
8 bytes. La utilidad de esta directiva se hace evidente cuando el cdigo escrito en
lenguaje ensamblador, es interactuar con el cdigo escrito en lenguaje C. El
compilador puede, en algunos casos (uso de nmeros de punto flotante, por ejemplo),
"exigir" este principio funcional para la pila del sistema. Por lo tanto es
normal encontrar una manera de especificar una alineacin sistemtica y tener as las
directivas que produce.

3.5.2. Directivas de gestin de


proyectos

La derrota de directiva permite la gestin y limitacin de la visibilidad de las


etiquetas. Esto es til para evitar la interferencia entre dos etiquetas similares. Una
etiqueta es una etiqueta con el nombre de formulario n {}, donde n es un nmero
(entre 1 y
99) que normalmente est prohibido porque teoricamente una etiqueta debe comenzar
con una letra. Por consiguiente, hacemos referencia la etiqueta %nNombre {}. Como
el nombre es opcional, la etiqueta puede ser slo un nmero. La directiva ROUT,
entonces, se utiliza para colocar el borde de visibilidad de las etiquetas.
42 Assembly Language Programming The Proper use of Assembly Directives 42

EJEMPLO 3.8.- El uso de rtulos de locales

Procedimiento ROUT. ; Derrota no significa rutina ! !


1
; Cdigo

3Procedimient ; Cdigo
o1
; Cdigo

BEQ %4Procedimiento1 ; No hay ninguna ambiged

; Cdigo

BGE %3 ; El objetivo es 3Proc

; Cdigo

4Procedimient ; Cdigo
o1
; Cdigo

Otros ROUT. ; Borde de visibilidad

BEQ %3 ; El objetivo es aho

; Cdigo

3Otros ; Cdigo

ROUT. Frontera ; pero sin la


opcin [nombre]
; Cdigo

3 ; Cdigo posible
demasiado...
; ... pero no muy
legible
B %3 ; rama a la etiqueta 3 ...

GET nombrearchivo
Filename INCBIN

Esto nos permite insertar (GET) el archivo nombre de archivo en el archivo actual.
En el caso de INCBIN, se supone que el archivo est binario ( datos sin procesar o un
tipo de archivo ejecutable .obj).

Mantenga el smbolo { }
43 Assembly Language Programming The Proper use of Assembly Directives 43

Indica al ensamblador que debe mantener los smbolos de la etiqueta de referencia en


la tabla de smbolos. En efecto, sin este aviso, el ensamblador no realiza un
seguimiento de los marcadores locales y slo conserva los elementos ms
significativos como, por ejemplo, las direcciones de los procedimientos.

Las siguientes directivas nos permiten establecer las condiciones para la inclusin
de elementos de la lista en un proyecto. Qu significa esto? Supongamos que desea
desarrollar algn cdigo que puede ser desarrollado en varias versiones para un
sistema. Supongamos que el 90% del cdigo es comn a todas las versiones, y que el
10% restante corresponde a las opciones. Cmo podemos manejar esto? Cualquiera
que haya tantas versiones del proyecto como usted tienen versiones del sistema, o slo
tiene un proyecto en el que algunas partes slo se incluyen si, durante la fase de
montaje, indique qu versin es.

EJEMPLO 3.9.- Uso del condicionado general

Versin GBLS Declaracin de una tecla (Cadena global)

Versin establece ? ? ? ; con ? ? ? "clsico" o "diseo"

rea MyCode, cdigo ;Apertura de una seccin de cdigo

Principales PROC

; parte comn del cdigo

Funcin BL1

B infinito infinito ;final del programa

rea MyCode, cdigo ;Apertura de una seccin de cdigo

;ooooooooooooooooooooooooooooooooo

Si la versin = "Clsico"

Funcin1 PROC

; cdigo para esta primera versin

ENDP

;ooooooooooooooooooooooooooooooooo

Versin ELSEIF = "diseo"

Funcin1 PROC
44 Assembly Language Programming The Proper use of Assembly Directives 44

. ; cdigo para esta segunda versin

ENDP

ENDIF

;ooooooooooooooooooooooooooooooooo

En el ejemplo 3.9, la funcin funcin1 existe en dos versiones. Es evidente que, si


no se agrega nada al cdigo, el vinculador ser confundido al encontrar dos idnticas
referencias a la misma funcin, y no sabra que elegir para finalizar la instruccin BL
Function1. Como la inclusin de una u otra de las dos versiones est condicionado
por la estructura if..ELSEIF..ENDIF, sin embargo, el ensamblador pondr a prueba
para averiguar qu parte del cdigo debe ser incluido en el proyecto. La otra parte es
simplemente ignorado. Tenga cuidado de no confundir: Cortex-M3 nunca ver
estas estructuras algortmicas. Asimismo, nunca se sabe de la existencia de
la versin general clave que permitieron la seleccin para tomar su lugar. Slo el
ensamblador sabe de esta clave, y por lo tanto no deberan confundirse con la idea de
una variable (podramos hablar de variables ambientales, pero ese trmino puede ser
confuso). El programador debe, al generar la versin de software que l o ella quiere
ofrecer, proporcionar la clave y sustituir el ??? Con el clsico o el diseo.

Existen varios tipos de llaves de ensamblaje: booleano (L), aritmtica (A) y la


cadena (S). Su creacin es llevada a cabo por una directiva (GBLx con x = L, A o S)
para una creacin mundial (lo cual es cierto para todos los archivos en el proyecto), o
una directiva LCLx para una creacin local (true slo para el archivo actual).
Un SETx directiva nos permite modificar el valor de esta clave. En el resto del cdigo,
el acondicionador de aire est situada dentro de la siguiente estructura:

Si Logic_Exp
; cdigo para incluir si Logic_Exp es true
Otra cosa
; cdigo para incluir cuando Logic_Exp es false
ENDIF

3.5.3. Directivas de diversos y variados

Lgica de ASSERT_Exp
45 Assembly Language Programming The Proper use of Assembly Directives 45

La mencionada directiva nos permite mostrar un mensaje (como un mensaje de


error) durante la segunda fase de montaje (un ensamblador toma varios pases para
llevar a cabo su trabajo). Si Logic_Exp es falsa.

Nombre CN expr

Nos permite cambiar el nombre de un registro en un coprocesador posibles:

Etiqueta { }{,fpliteral DCFSU fpliteral}...

Lo que nos permite inicializar reserva espacio en memoria para puntos flotantes.
Esto implica que el programa tiene acceso a las bibliotecas de clculo de punto
flotante y/o que una unidad aritmtica de punto flotante tipo coprocesador es
conectado a la estructura Cortex-M3.

Entrada

Lo anterior define el punto de entrada del programa. Esta directiva es esencial si


crea todo el cdigo. Si utiliza una biblioteca de inicializacin del procesador, se
integrar la gestin de punto de entrada. En este caso, debe evitar el uso de esta
directiva.

IMPORT EXPORT

Las dos directivas anteriores nos permiten compartir un smbolo (nombre de un


procedimiento, de una variable, etc.) entre varios archivos de un solo proyecto. Sus
ventajas y aplicaciones se explican en la seccin 9.1.5.
Captulo 4

Los operandos de las


instrucciones

Captulo 3 nos mostr cmo un programa escrito en lenguaje ensamblador est


formado. Ahora veamos las tcnicas en este idioma para acceder y manipular datos.
Esto implica definir qu es un operando. Primero, vamos a especificar que este
procesador tiene una estructura tipo load/store. Por consiguiente, slo es posible
acceder a zonas de memoria en la seccin de datos mediante instrucciones
especficas. Para estas instrucciones, uno de los operandos ser necesariamente la
direccin de una ubicacin de memoria donde se necesita leer o escribir. La manera
de describir esta direccin corresponde a la expresin el modo de direccionamiento y
sern cubiertos al final de este captulo.

Para ms instrucciones, los operandos son explcitamente valores dados (operando


inmediato), el contenido de los registros o etiquetas en el caso de la rama de
instrucciones. Con el fin de especificar qu operandos un programador desea utilizar
para llevar a cabo la operacin, l o ella escribe una expresin compuesta de nmeros
y smbolos.

Cuando la instruccin toma dos o tres operandos, como en el siguiente


ejemplo:

Instr op1,o2{,op3}

Op1 se llama destino operando. Es esta operando que recibe el resultado de la


operacin o de la asignacin. Operandos op2 y OP3 se denominan operandos de
origen, en la medida en que sirven para abastecer a la instruccin.

REMARK 4.1.- Para la lectura (LDR (registro) de carga, etc.) y escribir (STR (STore
Register), etc) instrucciones (vase la seccin 5.7), los significados de los operandos
origen y destino estn invertidas. Esta es una fuente de error cuando un programa
fuente escrito en lenguaje ensamblador, aunque en el nivel de instruccin, podemos ver
una cierta lgica.
48 Assembly Language Programming Operands of Instructions 48

4.1. La constante y cambio de nombre

En la seccin 3.1.1, nos explica las reglas para construir un smbolo as como
aquellos para expresar valores numricos (con o sin expresin literal), vase la
seccin 3.4.1. La manera ms sencilla de usar una combinacin de estas dos es la
declaracin de una constante. Una constante es un smbolo con el que se asocia un
valor fijo. Por lo que cada vez el ensamblador encuentra este smbolo, sabe que
simplemente debera sustituir el smbolo con el valor asociado. Usted hara bien si se
utiliza la funcin Buscar/Reemplazar en el editor de texto normal. Mediante una
constante en una lista tiene dos ventajas principales. La primera es que hace que la lista
sea ms fcil de leer (que no debe ser considerada un lujo) y la segunda es que nos
permite , cuando la constante se utiliza varias veces en el archivo, para llevar a cabo
una modificacin del valor en un solo lugar en el listado. El mantenimiento y el
desarrollo del programa, de este modo, es mucho ms fcil.

El EQU (equivalente) la directiva nos permite definir estas constantes. Aqu estn
algunos ejemplos:

EJEMPLO 4.1.- El uso de la directiva EQU

Loop EQU 12 ; versin bsica


TRUE EQU 0xFF ; el valor est expresado en base hexadecimal
FALSE EQU #0 ; Insertar un # para acceder de forma
inmediata el doble bucle EQU ; equivalencia doble...Por
qu no! Comenzar EQU principales ; La equivalencia es
una etiqueta char_G EQU 'G'
Msg EQU "Hello" ; imposible => General error!

El EQU declaracin no tiene ninguna consecuencia local, tan largo como el tercer
campo es una expresin que corresponde a un nmero entero de 32 bits constante 1.
Una cadena como el uno en la ltima lnea del ejemplo es imposible. Es necesario
estar alerta cuando se utiliza una constante en el resto de la lista, especialmente si se
trata de acceso a valores inmediatos, como los que trataremos en la siguiente seccin.
En efecto una instruccin como MOV
R0, verdadero donde verdadero es el constante declarada en el ejemplo 4.1, corre
el riesgo de ocasionar graves problemas, sobre la que volveremos.

1 Una etiqueta, como en la quinta lnea, corresponde a una direccin y por lo tanto tiene un
valor determinado de 32 bits.
49 Assembly Language Programming Operands of Instructions 49

La directiva RN (ReName) tambin puede hacer que la lista sea ms legible (aunque):

Nombre RN N

Donde n es un nmero entre 0 y 15 y sirve para identificar el registro general que es el


objetivo de la presente Directiva. La directiva nos permite renombrar la meta
registrarse con un nombre propuesto. Para contrarrestar la RN 0 nos permite utilizar
el smbolo contador en lugar del smbolo R0 en el resto del anuncio. Esto hace sentido
incluso si, al final, la desaparicin del nombre de un registro general en el listado puede
confundir un programador. Tambin puede desalentar definitivamente
futuros lectores escribiendo XV34_Z RN 1 y R_4 RN 2. El registro R2 se convertira
en R_4 y el registro R1 se convertira en XV34_Z. En trminos de legibilidad, esto no
me parece una mejora2!

4.2. Los operandos para instrucciones


comunes

Por instrucciones comunes, nos referimos al conjunto de instrucciones aparte de


las instrucciones de lectura y escritura.

4.2.1. Uso de registros

4.2.1.1. Registros
generales
En la mayora de instrucciones (y los ejemplos presentados aqu seguir este
enfoque), el programador se utilizan principalmente los registros generales
de R0 a R12 para almacenar los valores con los que l o ella lleva a cabo las instrucciones
comunes. Como tales, los registros podran considerarse las variables locales. Registros
generales son, pues, los operandos ms comunes que nos encontramos en un programa.
Pueden contener cantidades que expresan valores de muy distinta naturaleza (un entero
de 8 bits para el cdigo ASCII de un carcter, un entero sin signo de 16 bits para un
ndice de matriz, un entero firmado para un desplazamiento relativo en el programa,
etc.). Cualquiera que sea el caso, los 13 registros siempre ser visto por el procesador
como una cantidad codificada en 32 bits. El programador se enfrenta a dominar todo
el contenido de un registro cuando la informacin que l o ella est tratando con slo
contiene la mitad o una cuarta parte de ella.

Desde el punto de vista de codificacin, puede ser interesante ver lo que el cdigo
generado por el ensamblador parece. Tomemos la simple adicin
instruccin AGREGAR R0,R1 como un ejemplo. Esto agrega el valor contenido en los
dos registros y almacena el resultado en R0. Este resultado es a priori del pulgar tipo.
Su codificacin (y por lo tanto, lo que se almacena en la memoria de cdigo) es de 16
bits y su

2 No todos los registros son permitidos! Por ejemplo, R3 RN 4 es imposible.


50 Assembly Language Programming Operands of Instructions 50

Valor hexadecimal es sus 4,408. Veamos lo que el brazo documentacin especifica la


codificacin de esta instruccin (vase la figura 4.1).

Figura 4.1. 16-bit de la codificacin de la instruccin ADD

8 a 15-bits corresponden a peso el opcode de la instruccin. Los de 3 a 6 el nmero


de registro de cdigo de Peso RM, que debe corresponder a R1 para nosotros. Por lo
tanto, podemos esperar encontrar que Rm = 1 (o 0001 en binario). El DN como el bit
ms significativo combinado con los tres bits menos significativos de Rd da el nmero
del segundo registro, R0 en nuestro caso y hasta 0000 en binario. Cuando se reconstruye
este cdigo, por lo tanto, debemos tener 01000100|0|0001|000 = = 0100010000001000
0X4408, que coincide con el cdigo propuesto por el ensamblador.

La codificacin de instrucciones es un poco ms complicada que la que acabamos


de presentar. Afortunadamente, el programador no necesita ir en la diseccin de la
codificacin de las instrucciones para escribir correctamente el programa. Un
repositorio precisa de instrucciones diferentes posibilidades, felizmente, ser
ampliamente suficientes.

Es interesante constatar cmo la eleccin de registros puede influir en el tamao


del cdigo. Tomemos la instruccin que causa un OR lgico con el indicador
asignacin como un ejemplo: ORRS Rx, Ry. En la versin con el pulgar, los nmeros
de registro estn codificados en 3 bits (vase la figura 4.2). Adems, el uso de
registros R0 a R7 puede ser montado en la codificacin de 16 bits sin ningn
problema. En contraste, el uso de registros R8 a R12 ya no pueden ser codificados en
3 bits. El ensamblador es, por lo tanto, obligados a elegir pulgar-2 DE
CODIFICACIN, y la instruccin ser, pues, codificada en 32 bits. En este caso, la
codificacin se hace ms compleja y ORRS R1,R9 (mientras se hace la misma cosa) se
convertir en ORRS R1,R1,R9. Los tres registros utilizados estn codificados en 4 bits
(y por lo tanto no hay ms restricciones) y los campos imm3 y imm2 y tipo se usa para
codificar una hipottica offset (desplazamiento), como veremos al final de esta
seccin.

Pasar de 16 a 32 bits, una operacin aritmtica slo realmente representa una carga
adicional de dos bytes de la memoria, sino que tambin significa un aumento de 100%
en el tamao del cdigo. Si estamos tratando de optimizar el uso de la memoria, puede
ser til recordar esto y evitar llevar a cabo operaciones que utilizan los
registros R8 a R12 tanto como sea posible.
51 Assembly Language Programming Operands of Instructions 51

Figura 4.2. 16-bit y 32-bit de la codificacin de la instruccin ORRS

4.2.1.2. Otros registros


En la mayora de los casos los registros R13 y R14 actan como operandos, al igual
que los dems registros generales. Estos dos son diferentes, sin embargo, como se
corresponden directamente con el puntero de pila (SP) y el enlace Registrar (LR). Por
lo tanto, debemos tratarlas con precaucin.

En cuanto a la R15 registro (el puntero de instruccin), la mayora de las


instrucciones se niegan a trabajar con ella (como es demasiado peligroso) y el
ensamblador arrojar un error cuando viene a travs de tal uso. En cualquier caso, el
nico uso razonable de este registro es asignarlo a ejecutar subrutinas. Para ello, el
conjunto de instrucciones tiene todas las opciones de salto (B, BL, BX...) para
cubrir nuestras necesidades, as que no hay necesidad de jugar con fuego.

En cuanto a la xPSR registrar, ya hemos visto en el ejemplo 2.3 que dos


instrucciones especficas (MRS (pasar de especial para registrar) y MSR (Mover a
registro especial) nos permiten acceder a la xPSR. De nuevo, no hay ninguna razn
para querer hacer otra cosa.

Que apenas deja todos los dems registros que podemos encontrar en
un controlador (es decir, todo excepto el ncleo del procesador), y hay un montn!
En Cortex-M3 pertenecen al mundo exterior; todo este espacio de memoria slo es
accesible por cargar/guardar instrucciones. Vamos a ver en unas cuantas secciones
cmo acceder a ella. Tales registros no ser nunca operandos para instrucciones
comunes.
52 Assembly Language Programming Operands of Instructions 52

4.2.1.3. Shift
En el conjunto de instrucciones, al menos en la parte extendida de 32 bits (pulgar-
2), existe la opcin de imponer un cambio en el ltimo operando de origen. En el
ejemplo 4.2, lgico y se lleva a cabo: R0 y R1 (R2 <<3). Tenga en cuenta que el
sufijo S en la instruccin slo muestra dnde se colocarn las banderas para la
ejecucin.

EJEMPLO 4.2.- gica y un poco ms compleja

Ys.W R0,R1,R2,LSL #3

Por lo tanto, es posible introducir diferentes 3 turnos, a la izquierda o a la derecha


de la ltima fuente operando. Lo que puede parecer un truco sutil es, de hecho,
ampliamente utilizado por los compiladores. Recuerde que un desplazamiento a la
derecha de n bits equivale a multiplicar por 2 N (para un cambio de izquierda, sera
equivalente a dividir por 2N). Bien usado, esto puede ahorrar un montn de tiempo de
computacin.

En el caso de tres operandos, la sintaxis es como sigue:

Instr Ri, Rj , Rk LSL #n ; Mays izquierda lgica de n bits


Instr Ri, Rj, RK, LSR #n ; derecho lgico cambio de n bits
Instr Ri, Rj, RK, ASR #n; aritmtica Shift izquierda de n bits
Instr Ri, Rj, RK, ROR #n ; girar a la derecha en n bits
Instr Ri, Rj , Rk RRX ; girar a la derecha con la bandera C

En cada caso, los ndices I, j y k son enteros entre 0 y 12, y n es un nmero entero
entre 1 y 31. El cambio lgico introduce ceros a la derecha o a la izquierda. El
desplazamiento aritmtico reintroduce el bit ms significativo (por lo que el bit de
signo) a fin de evitar la prdida de la firma de la representacin de un nmero.
Rotacin copias bit a bit[0][31] con cada vuelta. Por ltimo, realiza una sola RRX 33
bits, rotacin de la 33 C la bandera.

REMARK 4.2.- El ejemplo anterior en realidad slo muestra tres operandos. De hecho,
el R2,LSL#3 slo es considerado uno de los operandos. Esta observacin es de menor
inters semntico.

3 Esta posibilidad est limitada a los 16 siguientes instrucciones aritmticas: ADC, agregar y,
BIC, CMN, CMP, EOR, Orn, ORR, RSB, SBC, SSAT, SUB EQT, TST y USAT.
53 Assembly Language Programming Operands of Instructions 53

4.2.2. El operando inmediato

4.2.2.1. Un caso clsico


La transferencia la instruccin mov R5#0x11 se compone de dos diferentes
tipos de operandos. Se modificar el primer operando (registro R5) con el segundo
operando (el valor 17=0x11). Este segundo operando es un operando inmediato. Esto
significa que es una parte integral de la instruccin: el operando inmediato ser
incluido en el cdigo de la instruccin, como se muestra en la codificacin de esta
instruccin (vase la figura 4.3). El ensamblador nos da el cdigo hexadecimal 2511.

Echemos un vistazo a la documentacin del brazo aqu: los 5 bits ms significativos


cdigo el opcode, bits de 8 a 10 el nmero de registro de cdigo (codificacin de 16
bits slo es posible para los registros R0 a R7) y el valor inmediato est codificada en
los 8 bits menos significativos. Tomando 101 como el cdigo
para R5, encontramos la espera, sabiendo que el cdigo
0010010100010001 = 0x2511.

Figura 4.3. Codificacin de 16 bits con MOVS operando inmediato

4.2.2.2. Un embarazoso caso


Qu sucede si el valor inmediato, que suponemos es unsigned en este ejemplo,
supera los 255? Inicialmente, como la codificacin de un nmero de registro para el
ejemplo de un OR lgico (vase la figura 4.2), el ensamblador cambiar a la
codificacin de 32 bits. Consultar la documentacin muestra que tambin es posible
especificar un operando inmediato codificada en 16 bits.

Vayamos an ms lejos. Como el registro R5 es de 32 bits, debe poder ser


inicializado con un inmediato valor codificado en 32 bits. Pruebe el siguiente ejemplo.

EJEMPLO 4.3.- problemtica un operando inmediato

MOV R5#0X1FF400 ; => Error de montaje

El fracaso! Ahora se enfrenta a Cortex-M3's Reduced Instruction Set Computer (RISC).


La arquitectura. El ensamblador devolver un mensaje descriptivo de desagrado, declarando
54 Assembly Language Programming Operands of Instructions 54

Que el operando excede la capacidad de representacin de un operando inmediato. Las


instrucciones estn codificadas en 16 o 32 bits y que no es posible apartarse de esta.
Por lo tanto, es perfectamente comprensible que un operando no puede utilizar todo
el espacio previsto para la instruccin de cdigo.

Brazo ofrece dos soluciones para este problema. La primera solucin parcial
implica el uso de registrar los cambios. Por ejemplo, la adicin de R0 a la inmediata
valor 0xff100 es imposible. No obstante, es posible cargar R1 con 0xFF10 y
agregar R0 a R1<<4.

El segundo enfoque es ms sistemtica, pero slo es vlido para la carga de un


registro y se basa en el uso de la LDR instruccin. Como veremos en la seccin
siguiente, LDR nos permite cargar un registro con el contenido de una memoria en la
que la direccin est indicado en el argumento. Tomemos nuestra lnea de cdigo
anterior y sustituirlo con el siguiente ejemplo.

EJEMPLO 4.4.- menos problemtico pseudo-


operando

LDR , R5=0x1FF400 ; => OK para el ensamblador

Ahora no hay ningn problema en el lado del montador. Pensamos que podemos,
con sintaxis ligeramente diferente, utilice un operando inmediato. En realidad
el verdadero cdigo cargado para esta instruccin, en el sentido de que nos
encontraramos en una operacin de desmontaje, se ve algo como ejemplo 4.5.

EJEMPLO 4.5.- Pero, dnde est el operando inmediato pasado?

LDR R5,[PC,#18] ; => OK para el ensamblador

[PC,#18] significa que el procesador debe recuperar el contenido de la direccin encuentra


18 direcciones por encima de la direccin actual del puntero de instruccioneso
contador de programa ( PC). El valor 18 es definido aqu como un ejemplo. Este
desplazamiento es generalmente un nmero n. Dejemos de lado por el momento el
direccionamiento indirecto (reconocible por el uso de []), y basta con mirar el
principio. Esquemticamente la colocacin de los contenedores y los contenidos se
implementa tal como se muestra en la Figura 4.4.

Una instruccin como LDR Ri =expr, donde expr es un valor expresado en alguna
base o de otro tipo, es un pseudo-instruccin. Dependiendo del valor de expr, el
ensamblador generar diferentes de codificacin:
- Si expr puede ser codificados en 8 bits, la instruccin mov Ri, #expr;
55 Assembly Language Programming Operands of Instructions 55

- Si expr puede ser codificado en 16 bits, la instruccin mov.W ri,#expr;


De lo contrario
- LDR Ri,{PC #desplazamiento], donde el desplazamiento es un desplazamiento
relativo con respecto a la posicin actual del puntero de la instruccin PC, lo que nos
permite llegar a la piscina donde el valor literal ser creado.

Figura 4.4. Carga de un operando inmediato de 32 bits

4.2.2.3. La piscina y el LTORG literal de la directiva


Por su propia iniciativa, cuando sea necesario el ensamblador crear zonas de
memoria para almacenar valores de inmediato que no se incluyen directamente en el
cdigo de la instruccin. Estas zonas se denominan pools Literal. Se crean por defecto
al final de cada seccin de cdigo. Esta proximidad relativa impide el desplazamiento
relativo que deben aadirse al puntero pc alcance un valor demasiado grande. De
hecho, este desplazamiento debe ser menor de 4.096 (en el escenario ideal para la
codificacin de 32 bits). Cuando el pseudo- instruccin LDR Rd, =expr debe poner un
valor inmediato en un literal de piscina, el ensamblador primero comprueba que
este valor no ha sido previamente creado; si lo ha hecho, el ensamblador determina si
puede ser alcanzado (desplazamiento relativo <4.096) para
56 Assembly Language Programming Operands of Instructions 56

Que pueda ser utilizada. Si no se cumplen estas dos condiciones, se crea esta
constante en el Literal siguiente Pool.

EJEMPLO 4.6.- El uso de la directiva LTORG

;*************************************************************
******

; seccin de cdigo

;*************************************************************
******

MyCode, cdigo de rea, readonly, ALIGN=6

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Procedimiento principal ;

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Principales PROC ; Inicio del programa

LDR, R5=0x1ffff ; Carga de un valor inmediato

BL DoNothing ; llamada al procedimiento DoNothing

Inf B inf ; bucle infinito

LTORG ; la apertura de una piscina


literal

DoNothing PROC

NOP ; hacer nada...

BX LR ; ... y volver

ENDP

Espacio EmptyResa 5000 ; reserva "alejarse"

; la seccin final

ENDP

;*******************************************************************
57 Assembly Language Programming Operands of Instructions 57

Sin embargo, an es posible para el final de la seccin a ser demasiado lejos para
considerar esta manipulacin implcita. Tambin existe la opcin de forzar la creacin
de una zona de almacenamiento utilizando la directiva LTORG.

En el ejemplo 4.6, la directiva LTORG se coloca entre el procedimiento principal


y el DoNothing funcin. El rea de almacenamiento sera, por lo tanto, se inserta en
esta ubicacin. Hemos podido comprobar tambin que la instruccin LDR R5,
=0x1FFFF en esta configuracin corresponde a la LDR R5,[PC,#8]. Sin usar
esta directiva, el ensamblador habra estado fallando como los
5.000 bytes EmptyResa reserva de la etiqueta en la misma seccin de cdigo implica
que el literal siguiente piscina est demasiado lejos como para ser alcanzado con
un desplazamiento de <4.096.

4.3. Memory access operandos: modos de direccionamiento

Es evidente que no todos los datos de un programa puede ser enteramente


contenida en los registros. Por lo tanto, es necesario durante la ejecucin de un
programa para recuperar operandos fuente (leer) o para depositar los operandos
destino (escribir) en la memoria. Estas son las operaciones de carga/almacenamiento.
Muchas variaciones de estas instrucciones se pueden utilizar, pero en general pueden
clasificarse en dos tipos de operacin:

LDR Ri, {expr}


STR Ri, {expr}

{expr} es una expresin que nos permite calcular la direccin donde el valor que se
va a establecer como valor de Ri sern ledos (LDR) o donde el valor contenido en el
registro Ri ser almacenado (STR). Algunas notas importantes sobre esta sintaxis:
- esta expresin siempre contiene al menos un registro general. Generalmente se
llama la base registrarse porque va a definir una direccin base a partir del cual se
producir de acceso a la memoria.
- el concepto y el significado habitual de origen/destino operandos para
instrucciones comunes no se aplica aqu.
- el registro base puede cambiar (incremento o decremento) con la ejecucin de la
instruccin. Las diferentes posibilidades de estos cambios reflejan los modos de
direccionamiento.
- el uso de estas instrucciones es necesaria en el curso de un programa, pero ellos
son los que causan ms problemas. De hecho, si a consecuencia de una mala
manipulacin, el registro base contiene un valor incorrecto y un bug est garantizada.
58 Assembly Language Programming Operands of Instructions 58

- las diferentes variaciones corresponden a diferentes teclas pero siempre contendr


la LDR radical o str. Especialmente podemos distinguir:
- aquellas que autorizan la lectura o escritura de un byte (LDRB, STRB), un semi-
word (LDRH, STRH), e incluso aquellas que causan varias lecturas/escrituras (LDRD,
STD, LDM, STM, etc.)
- aquellas que nos permiten especificar si un dato para ser ledo est firmado
(LDRBS, LDRSH, etc.), y finalmente
- Aquellos que estn vinculados con los privilegios de acceso a la memoria o la
proteccin (LRDEX,
LDRBT, etc.);
- no hay acceso directo a la memoria (a diferencia de lo que ocurre en otros
idiomas, como el conjunto de los de Intel, Motorola, microchip, etc.);
- por lo tanto, es siempre necesario proceder en dos pasos: uno para recuperar la
direccin en un registro y un segundo para acceder a la memoria a travs de este
registro.
- la sintaxis LDR Ri=val es ficticia. Siempre ser traducido como
MOV Ri#val o LDR Ri, [PC,#n].

4.3.1. El concepto de puntero

{expr} contiene al menos un registro que contiene la direccin base. Por lo tanto,
aqu nos encontramos con el concepto de un puntero que encontramos en un nivel
superior de la estructura del lenguaje. En lenguaje ensamblador, lo ms a menudo
utilizan trminos de direccionamiento indirecto. El principio ya ha sido ilustrada
mediante la LDRB R3,[R6] instruccin presentada en la Figura 3.2. R6 es un puntero
que por tanto (por la propia definicin de un puntero) contiene una direccin en la que
el procesador puede leer una instruccin para modificar el destino operando (R3 en
este ejemplo). El uso de corchetes ([ y ]) alrededor del nombre de registro nos permite
indicar al ensamblador que estamos interesados en el contenido de la direccin
almacenada en el registro, en lugar de contenido del registro en s. El
nemotcnico LDRB fue usada en este ejemplo; el procesador, por lo tanto, slo leer
un byte que considere unsigned (LDRSB le permite tomar en cuenta el signo). De esta
manera, los tres bytes ms significativos sera 0, de forma que el valor de 32 bits
eventualmente contenidos en R3 se corresponde con el valor de 8 bits que figura en la
direccin de origen. En este caso, estamos hablando de promocin sin firmar (firmado
en la promocin, el bit ms significativo sera copiada en los 24 bits ms
significativos del registro de modo que los valores de 8 bits y 32 bits corresponden a
la misma cantidad firmado).

Un detalle que queda por resolver: cmo fue la direccin contenida


en R6 especificado? Hablando en trminos de lenguaje estructurado: cmo fue el
puntero inicializado? Simplemente usando la sintaxis detallada en la seccin
4.2.2: LDR Ri, =imm32. En los anteriormente citados
59 Assembly Language Programming Operands of Instructions 59

Ejemplo, R3 es inicializado por la LDR, R3=Bytinit. Con esta formulacin de


instrucciones, como se ha mencionado en esta seccin, tratamos con direccionamiento
inmediato. El valor inmediato es la direccin de 32 bits de la variable Bytinit. El
ensamblador por lo tanto espera el almacenamiento de esta informacin inmediata en
la piscina y literal el cdigo embebido corresponder a una LDR
R3,[PC,#Offset offset] , donde es el valor relativo que nos permite llegar a la zona de
la piscina Literal. As nos tienen implcitamente un primer acceso indirecto para leer
la direccin de la variable donde hemos encontrado nuestro datum.

Esquemticamente, las dos lneas de cdigo ( y ) en este ejemplo implica, por lo


tanto, doble apuntando, como se resume en la Figura 4.5. Es la nica manera de tener
acceso al contenido de una variable.

Figura 4.5. Inicializacin y uso de un puntero

4.3.2. Modos de
direccionamiento

Cuando se utiliza direccionamiento indirecto simple [Ri], la direccin de destino


de la transferencia est explcitamente contenida en el ri registrarse.

La sintaxis para ejecutar ms simple la lectura de un semi-palabra en la memoria,


"sealado" por registrar Rn y la transferencia en el registro Rn corresponde por tanto
a la siguiente sintaxis:

LDRH Rt, [Rn]


60 Assembly Language Programming Operands of Instructions 60

Existen otros tres modos de direccionamiento, sin embargo, para que este vnculo
es menos directa. En cuanto a la sintaxis presentada anteriormente, la explicacin de
estos modos de direccionamiento se ilustra a travs de la instruccin para cargar una
media palabra a un registro, pero estos modos son tambin para escribir (STRH) y para
las diferentes variaciones de la nemotecnia LDR y STR.

4.3.2.1. Direccionamiento indirecto con desplazamiento


En este modo de direccionamiento, agregamos un desplazamiento adicional
(offset) a la direccin que figura en el registro base. La sintaxis es:

LDRH Rt, [Rn, #desplazamiento]

El principio de esta transferencia se muestra en la Figura 4.6a. Debemos tener en


cuenta que el valor de la desviacin es, en la mayora de los casos, limitada a
4.096, pero para algunos formularios especiales (LDRHT, por ejemplo) el valor
mximo puede ser inferior. Esta cantidad, al igual que cualquier valor inmediato en
una instruccin, tambin puede influir en el tamao de la codificacin (16 o 32 bits).

Uno de los principales usos de este modo de direccionamiento es para acceder a


estructuras de datos. Slo la direccin de la estructura es conocida. Esto puede ser
depositado en el registro base. Para acceder a otros campos de la estructura
constituyente, debemos usar el desplazamiento para especificar el desplazamiento
relativo a imponerse para llegar a este campo (vase la seccin 6.5).

Figura 4.6. Transferencia: (a) con compensacin inmediata; (b) con el ndice
61 Assembly Language Programming Operands of Instructions 61

4.3.2.2. Modo de direccionamiento indirecto con ndice


En este modo, la direccin est formada por la adicin de dos registros. La
sintaxis es como sigue:

LDRH Rt, Rn, [Rm]


LDRH Rt, [Rn, Rm {, LSL #<imm2>}] ; alternativa con Mays izquierda

Con este modo, es bastante fcil de codificar un algoritmo mediante una tabla:
todo lo que tenemos que hacer es poner la direccin de la tabla en el registro Rn y el
ndice de la tabla en la Rm registrarse.

Una lnea de cdigo en C como Local = [ndice] se traducira en lenguaje


ensamblador, como la lnea LDRH [R3, R6, R1] (vase la figura 4.6).

REMARK. 4.3.- Cuando queremos acceder a la n-sima componente de una tabla tpica,
es conveniente utilizar el operador de desplazamiento como se presenta en la sintaxis
anterior. As, para una tabla que contiene enteros largos codificada en cuatro bytes,
colocando R6 en la direccin de esta tabla y poniendo un valor k en R1, la instruccin
LDR [R3, R6, R1, LSL#2] nos permite leer los k th elemento de la tabla.

4.3.2.3. Modo de direccionamiento indirecto con post-


Modificacin
En los dos modos anteriores, el registro base no fue modificada por la instruccin.
Esta prctica es totalmente compatible con la gestin de tablas o estructuras de datos
para que las direcciones siempre son fijos.

En este tercer modo (y por la que sern presentados en la siguiente seccin),


el valor del registro base ser modificado por la instruccin. Esta gestin
corresponde perfectamente al concepto de puntero encontrados en los lenguajes de
alto nivel: Cuando usamos el puntero, el registro base puede evolucionar. Por lo tanto,
es intrnsecamente una cantidad variable.

De este modo primero, la modificacin del registro ocurre justo despus de la


ejecucin de la transferencia, utilizando la siguiente sintaxis:

LDRH Rt,[Rn] #imm8

As, la ejecucin tiene dos efectos sucesivos: la asignacin del registro Rt con el
contenido de la direccin almacenada en el registro Rn, luego la modificacin del
puntero como sigue: Rn Rn imm8.
62 Assembly Language Programming Operands of Instructions 62

REMARK 4.4.- La sintaxis es bastante similar al que se usa para el direccionamiento


indirecto con desplazamiento. Slo la posicin de corto plazo (dentro o fuera de los
corchetes) cambios, que pueden ser una fuente de confusin, especialmente cuando
vuelva a leer el anuncio.

En el ejemplo de la Figura 4.7, el valor de la desviacin es positiva (+4). Debemos


tener en cuenta que la modificacin del puntero no slo es unitario, obligatoriamente,
pero que tambin puede ser negativo. Debe estar entre -127 y +128

4.3.2.4. Direccionamiento indirecto con post


modificacin
En este caso, la modificacin se produce antes de la transferencia:

LDRH Rt, [Rn #imm8] !

La ejecucin se produce tambin en dos pasos (vase la figura 4.7). En el primer


paso, obtenemos la modificacin del registro base Rn Rn imm8. En el segundo
paso, la nueva cantidad de destino se transfiere al registro Rt.

REMARK 4.5.- Es importante elegir una buena fuente para el editor de texto de forma
que no se pierda el "!" que sigue a los soportes.

Figura 4.7. Transferencia: (a) con post-modificacin; (b) antes de la modificacin


Captulo 5

Conjunto de
instrucciones

La lectura de un conjunto de instrucciones no es nada agradable. En su primera


lectura de este captulo, los lectores simplemente ojear, pero al final, este
es definitivamente el captulo en el que el usuario volver a la mayora a menudo para
averiguar lo que el procesador puede hacer y sobre todo cmo l o ella puede hacer
eso (es decir, con qu operandos).

5.1. Gua de lectura

Un cierto nmero de convenciones, omisiones o las reglas implcitas que rigen la


recopilacin de las explicaciones de la instruccin set. Por consiguiente, es necesario
leer estas secciones, teniendo en cuenta las siguientes observaciones:
- algunas instrucciones slo se mencionan (al final del captulo) y no se explican.
Son instrucciones avanzadas para el procesador y por lo tanto estn dirigidos a
programadores avanzados que no sera, en cualquier caso, estar satisfecho con este
nico libro.
- la mayora de las instrucciones estn en un 16 o la versin de 32 bits. El
ensamblador, segn sus propias reglas implcitas y lmites funcionales (el tamao de
los operandos inmediatos, por ejemplo) se elige uno o el otro. No obstante, es posible
forzar el cdigo deseado tamao agregando .W para un 32-bit o .N para una extensin
de 16 bits. Al hacerlo, esto puede conducir a un mayor dominio del cdigo proceso
de fabricacin pero a expensas del fallo en el caso de que sea imposible para el cdigo
de la instruccin en el cdigo con el sufijo <p>. En este libro se indicar nicamente
los tamaos (16, 16/32 32 bits) para cada instruccin, quedando entendido que la
ejecucin forzosa slo es razonable si el tamao no es fijo.
64 Assembly Language Programming Instruction Set 64

REMARK 5.1.- W significa palabra pero a veces (como en este captulo), esto
significa que una cantidad de 32 bits y algunas veces (como en el caso de la
directiva DCW) una cantidad de 16 bits. En otros lugares los
Cantidad de 16 bits puede ser caracterizada por el uso de unsemi-H ( Word) o mediante el uso
de
.n, tal como se ha explicado anteriormente. No es terriblemente complicado, pero es
terriblemente incmodo y una fuente de particularmente molesto pequeos errores:
- para muchas instrucciones es posible aadir un sufijo que luego nos permite
condicionar la ejecucin de la instruccin. La opcin de agregar este sufijo se muestra
en la tabla por el smbolo <c>. La adicin de este sufijo no es sin consecuencias para
el cdigo generado por el ensamblador porque esto equivale a insertar una instruccin
en frente de la instruccin propiamente dicha. Por lo tanto, es necesario recordar esto,
especialmente durante el desarrollo de las secuencias en las que esta instruccin puede
aparecer incluso si el programador no ha escrito explcitamente. Tambin es necesario
recordar que el condicionamiento es relativa al estado de las banderas, que en s
mismos son generalmente asignado por la instruccin anterior que s debe ser
condicionada. La lista de sufijos est dado por la tabla 5.1 con las condiciones y la
lgica Combinacin de indicadores relativos a cada condicin;
- para varias instrucciones, es necesario hacer la distincin entre las menos
importantes y ms significativos los bits del operando. En aras de la portabilidad, las
abreviaturas LSB (bit menos significativo) y MSB (bit ms significativo) se han
utilizado para hacer esta distincin.
- Para las instrucciones comunes el primer operando es presentada a menudo como
siendo opcional. En las siguientes tablas se describen las diferentes instrucciones,
esto generalmente se muestra mediante un {Rn} para el destinatario operando. Si el
destinatario no est operando de forma explcita , sin embargo, dado el primer
operando se comporta como el origen y el destino a la vez. Por ejemplo, en Agregar
R0,#2, el registro R0 es el origen y el destino y
Esta instruccin significa R0R0+2.

Los registros generales son indiscriminadamente denotada


por Rd, Rn, Rm o ra para instrucciones comunes. Sin embargo, no es necesario para
una instruccin para comprobar d n
m una y a priori con a, d, m, n :
- [015]. Por lo tanto, la instruccin agrega.W R1,R1,R1 es bastante permisible y
demuestra que R1 recibe el doble de su contenido y que el sufijo banderas (S) ser
actualizada.
- para leer/escribir instrucciones, el registro base es Rn y el registro que
recibe/suministra los datos se denomina Rt;
- la expresin M32(Rn) significa el contenido de 32 bits de la direccin apuntada
por Rn y las tres direcciones siguientes;
- <Mays> operador aparece (opcional operador para ms instrucciones) para
imponer un poco cambio en el ltimo operando en la lista. La lista de los posibles
cambios es el mismo que el presentado en la seccin 4.2.1.1.
65 Assembly Language Programming Instruction Set 65

5.1.1. Lista de posibles "condicin" los sufijos

Tabla 5.1 corresponde a las posibles sustituciones para el smbolo <c>. Cabe
sealar que esto se aplica tambin a las instrucciones de salto (B, BL, BX, etc.)que
luego son condicionados. En el caso de sucursales de estas instrucciones, la
instruccin no se inserta antes del salto.

Sufijo Condicin Band


eras
EQ Igual Z=1
NE No igual Z = 0.
CS Llevar Set
C=1
HS Mayor o igual
CC Claro llevar
C=0
BA Bajar
JA
MI Menos N=1
PL PLus N=0
VS Conjunto de V=1
desbordamiento
VC Claro desbordamiento V=0
Ho Unsigned superior (C = 1 y Z = 0)
la
LS Unsigned inferior o igual (C = 0 o Z = 1).
GE Firmado igual o superior N=V
LT Firmado menos de NV
GT Firmado superior Z=0yN=V
LE Firmado igual o inferior Z=1oNV

Tabla 5.1. Lista de posibles


condiciones

Cuando aplicamos diferentes estructuras algortmicas, a menudo es necesario


programar acondicionado salta tras una comparacin de las dos cantidades.
Dependiendo de si las cantidades son signed o unsigned, y si queremos una
comparacin estricta o no, el mnemnico cambios. Cuadro 5.2 reanuda la lista de
condiciones posibles para permitir la codificacin de la rama condicionado al que
seguir un CMP x,y sin demasiadas preguntas.
66 Assembly Language Programming Instruction Set 66

CMP x,y ... B ? ?


Firmado Unsigned
X,Y. X,Y.

= EQ EQ
< MI LO
LE LS
> GT Ho
GE la
HS

Cuadro 5.2. Uso de sufijos de condicin para la comparacin de dos


enteros
(Consulte la Tabla 5.1 para obtener una explicacin de
las abreviaturas)

Ahora para la larga y tediosa lista de instrucciones. Estas se clasifican en familias


grandes para facilitar la bsqueda por temas. El apndice es una versin abreviada de
este captulo, pero las instrucciones estn ordenadas en orden alfabtico.

Empecemos con la primera instruccin inclasificable:

NOP 16/32 No hay funcionamiento


NOP<c> No
hacer nada un poco
No sirve ningn propsito distinto al utilizar
de tiempo de CPU. Nota sorprendente sutileza: NOP
puede ser acondicionado
De modo que "no hacer nada" si la condicin es falsa!

5.2. Instrucciones aritmticas

ADC 16/32 Adems de llevar


ADC{S}<c> {<Rd>} <Rn> # <const.> Rd rn + const.
+ la
ADC{S}<c> {<Rd>} <Rn> <Rm> {<Mays>} Rd Rn bandera
+Mays(RM)C
El uso del registro SP hace una llamada a una codificacin+ la
especfica; esta es la razn por la que aparece explcitamentebandera
C
en esta lista. Sin embargo, no tiene limitaciones especficas en
cuanto a su uso.
67 Assembly Language Programming Instruction Set 67

Agre 16/32 Simple adicin


gar
Aadir{S}<c> {<Rd>} <Rn>#<const.> Rd rn + const.
Aadir{S}<c> {<Rd>} <Rn> <Rm> {<Mays>} Rd rn + shift(RM)
Aadir{S}<c> {<Rd>} SP, #<const.> Rd SP + const.
Aadir{S}<c> {<Rd>} SP, <Rm>{<Mays>} Rd SP + shift(RM)

MLA 32 Sumas y multiplicaciones


MLA<c> <Rd> <Rn> <Rm> <RA> Rd (Rn * Rm) + Ra
Adems se convierte en una acumulacin cuando Rd = Ra
(Vea las instrucciones SMLAL para una acumulacin de 64
bits).

MLS 32 La multiplicacin y la resta


MLS<c> <Rd> <Rn> <Rm> <RA> Rd Ra - (Rn * Rm)

MUL 16/32 Multiplicacin - resultados de


32 bits
MUL{S}<c> {<Rd>} <Rn> <Rm> Rd Rn * RM
Ser conscientes de que el resultado slo contiene
los 32 bits LSB. No tener en cuenta el signo del
resultado.
La instruccin, por lo tanto, slo tiene sentido si los operandos son
fuente de 16 bits. Debemos utilizar SMUL para obtener un
resultado de 64 bits.

RSB 16/32 Sustraccin inversa


RSB{S}<c> {<Rd>} <Rn> # <const.> Rd -rn + const.
RSB{S}<c> {<Rd>} <Rn> <Rm> {<Mays>} Rd -rn + shift(RM)
Vase tambin la instruccin Sub con respecto a sustracciones.
68 Assembly Language Programming Instruction Set 68

SBC 16/32 Resta con llevar


SBC{S}<c> {<Rd>} <Rn> # <const.> Rd Rm - const.
+ la
SBC{S}<c> {<Rd>} <Rn> <Rm> {<Mays>} Rd RM - bandera
CAMBIO(RM)C

Codificacin de la versin con "const" est siempre en 32+ bits.


la
bandera
C

SDIV 32 Divisin firmado


SDIV<c> {<Rd>} <Rn> <Rm> Rd Rn Rn
La divisin de enteros de operandos de 32 bits: el resto se pierde!

SMLAL 32 Firmada la multiplicacin y la adicin de 64


bits
SMLAL<c> <Rdlsb >, <RMSB >, <Rn> <Rm> [Rd Rdlsb msb :] Rn * RM
+[Rd Rdlsb msb :]
[Rd Rdlsb msb :] es una de 64 bits pseudo registrarse compuesta de
dos registros de 32 bits.
Es una instruccin muy til para el procesamiento
de la seal.
SMULL 32 Multiplicacin firmado - resultados de
64 bits
SMULL<c> <Rdlsb>, <Rdmsb>, <Rn> <Rm> [Rd Rdlsb msb :] Rn * RM
Esta instruccin complementa MUL para operandos de 32 bits.

SSAT 32 Saturacin
firmado
SSAT<c> <rd#><imm5><Rn>{<Mays>} Si (Rn < 0) Rd
Min(-2(imm5-1),Mayus
(Rn)
Si (Rn >0) Rd
imm5-1
Max(2(
La bandera est configurada para q yo si ha ) - 1,Mayus
habido saturacin, de
(Rn)
lo contrario, permanece inalterado. La bandera q se puede ajustar
a 0 antes de la operacin, a fin de explotar esta informacin. La
saturacin es una importante operando
Algoritmos para trabajar en la representacin de un punto
fijo.
69 Assembly Language Programming Instruction Set 69

SUB 16/32 Una simple resta


SUB{S}<c> >} {<Rd ,<Rn>#<const.> Rd Rn - const.
SUB{S}<c> >} {<Rd ,<Rn> <Rm> {<Mays>} Rd Rn -
SUB{S}<c> >} {<Rd ,SP,#<const.> cambio(RM)
Rd SP - const.
SUB{S}<c> >} {<Rd ,SP,<Rm> {<Mays>} Rd SP -
cambio(RM)
Vase tambin la RSB instruccin acerca de sustracciones.
El uso de los SP registracin exige el uso de una
codificacin especfica. Esta es la razn por la que aparece
explcitamente en esta lista.

UDIV 32 Divisin sin signo


UDIV<c> {<Rd>} <Rn> <Rm> Rd Rn RM

UMAL 32 Multiplicacin sin signo de 64 bits y adems


UMLAL<c> <Rdlsb >, <Rdmsb>, <Rn> <Rm> [Rd Rdlsb msb :]Rn*RM
+ [Rd Rdlsb msb :]
[Rd Rdlsb msb :] es una de 64 bits pseudo-registro compuesto de
dos registros de 32 bits.

UMULL 32 Multiplicacin sin signo de 64 bits -


Resultados
UMUL<c> <Rdlsb >, <Rdmsb >, <Rn> <Rm> [Rd Rdlsb msb :]Rn*RM
[Rd Rdlsb msb :] es una de 64 bits pseudo-registro compuesto de dos registros
de 32 bits.

USAT 32 Saturacin sin firmar


USAT<c> <rd#><imm5><Rn>{<Mays>} Rd
Max(2(imm5-1) - 1 ,
La bandera est configurada para q yo si SHIFT(Rn)
ha habido saturacin, de
lo contrario Q permaneci inalterado. La bandera q se puede
ajustar a 0 antes de la operacin, a fin de explotar esta informacin.
La saturacin es una importante operando con algoritmos
trabajando en la representacin de un punto fijo.
70 Assembly Language Programming Instruction Set 70

5.3. Instrucciones de manipulacin de bits y lgico

Y 16/32 Y lgico
Y{S}<c> {<Rd>} <Rn> # <const.> Rd Rn y const.
Y{S}<c> {<Rd>} <Rn> <Rm> {<Mays>} Rn Rn y shift(RM)

ASR 16/32 Derecho de


desplazamiento
ASR{S}<c> <Rd> <Rm> #<imm5> Rd Rm >>imm5
aritmtico
ASR{S}<c> <Rd> <Rn> <Rm> Rd Rn >>rm
El cambio reintroduce la izquierda firmado poco. El ltimo
bit que sale a la derecha modifica el llevar C
bandera.

BFC 32 Campo de bits


Borrar
BFC<c> <Rd> #<LSB> #<Nb> Rd[lsb+Nb-1 : lsb] 0
Lsb = 0 ... 31 y Nb = 1 ... 32.
Esta instruccin no tiene un pabelln de modificar la
versin.

BFI 32 Campo de bits Copiar


BFI<c> <Rd><Rn> #<LSB> #<Nb> Rd[lsb+Nb-1 : lsb] Rn[Nota:
Lsb = 0 ... 31 y Nb0]
= 1 ... 32.
Esta instruccin no tiene un pabelln de modificar la
versin. La instruccin simtrico permite que la copia
de un determinado campo de bits en el que los LSBs de
Rd no existen.

BIC 16/32 Borrado y mscara de bits


por
BIC{S}<c> {<Rd>} <Rn> # <const.> Rd Rn Y NO(const)
BIC{S}<c> {<Rd>} <Rn> <Rm> {<Mays>} Rd Rn Y NO (shift(Rm))
Lsb = 0 ... 31 y Nb = 1 ... 32.
71 Assembly Language Programming Instruction Set 71

CLZ 32 Cuenta regresiva las MSBs a 0 antes de que el


primer bit a 1
CLZ<c> <Rd> <Rm> Rd CLZ(Rn)
Rd obtiene un valor entre 0 (RD = 0xFFFFFFF) y 32 (RD = 0).
Esta es una instruccin potencialmente interesante para
los algoritmos que trabajan sobre la representacin de
un punto fijo.

EOR 16/32 Exclusivo o


EOR{S}<c> {<Rd>} <Rn> # <const.> Rd Rn XOR const.
EOR{S}<c> {<Rd>} <Rn> <Rm> {<Mays>} Rd Rn XOR shift(RM)
Esta es una instruccin provechosa para invertir los campos
de bits.

LSL 16/32 Cambio lgico


izquierda
LSL{S}<c> <Rd> <Rm> #<imm5> Rd Rm <<imm5
LSL{S}<c> <Rd> <Rn> <Rm> Rd Rn <<RM
El cambio introduce ceros a la
derecha.
El ltimo bit dejando a la izquierda modifica el llevar C
bandera.

LSR 16/32 Cambio lgico


derecho
LSR{S}<c> <Rd> <Rm> #<imm5> Rd Rm >>imm5
LSR{S}<c> <Rd> <Rn> <Rm> Rd Rn >>rm
El cambio introduce ceros a la
izquierda.
El ltimo bit que sale a la derecha modifica el llevar C
bandera.

MVN 16/32 Complemento lgico a 1


MVN{S}<c> <Rd> # <const.> Rd no (const)
MVN{S}<c> <Rd> <Rm> { <Mays>} Rd NO(Mayus (Rn)
72 Assembly Language Programming Instruction Set 72

NEG 16/32 Negativo (complemento a 2)


NEG<c> {<Rd>} <Rm> Rd -RM
NEG es equivalente a RSB con 0. No hay codificacin especial para este
mnemnico.

El 16/32 Complementan O lgico


ElORN
ORN{S}<c> {<Rd>} <Rn> # <const.> Rd RM
O NO(const)
El ORN{S}<c> {<Rd>} <Rn> <Rm> {<Mays>} Rd RM
O NO(shift(Rm))

ORR 16/32 O lgico


ORR{S}<c> {<Rd>} <Rn> # <const.> Rd Rm o const.
ORR{S}<c> {<Rd>} <Rn> <Rm> {<Mays>} Rd Rm o shift(RM)

RBIT 32 Transposicin de
bits
RBIT<c> <Rd> <Rm> Rd[31-k] Rm[k] con k = 0 ... 31

REV 16/32 Reversin de las MSBs y


LSBs
REV<c> <Rd> <Rm> Rd[31 : 24] Rm[7 : 0]
Rd[23 : 16] Rm[15 : 8]
Rd[15 : 8] Rm[23 : 16]
Rd[7 : 0] Rm[31 : 24]
La unidad aritmtico-lgica slo funciona en 32 bits.
A menudo es necesario realizar este tipo
De traslado al trabajo en representaciones
ms pequeas.
73 Assembly Language Programming Instruction Set 73

REV16 16/32
Reversin de las MSBs y LSBs media
palabra
REV16<c> <Rd> <Rm> Rd[31 : 24] Rm[23 : 1]
Rd[23 : 16] Rm[31 : 24]
Rd[15 : 8] Rm[7 : 0]
Rd[7 : 0] Rm[15 : 8]
Vase el comentario sobre el REV instruccin.

REVSH 16/32 Revocacin firmada por media


palabra
REVSH<c> <Rd> <Rm> Rd[31 : 8] firmado promocin (Rm[7] :
0) Rd[7 : 0] Rm[15 :
8]

ROR 16/32 Rotacin a la derecha


ROR{S}<c> <Rd> <Rm> #<imm5> Rd rotacin(Rm, imm5 bits)
ROR{S}<c> <Rd> <Rn> <Rm> Rd rotacin(Rn, Rm bits)
La rotacin reinserts bit 0 en 31 bits con cada
vuelta.
No hay rotacin de n bits a la izquierda como
esta sera una rotacin de 32-n bits a la
derecha.
RRX 32 Rotacin derecha
ampliada
ROR{S}<c> <Rd> <Rn> <Rm> Rd rotacin([Rn,C], Rm bits
Este utiliza el mismo principio que ROR, pero con el indicador C en la
33bit a la derecha. No hay ningn formulario con operando inmediato
para esta instruccin.

SBFX 32 32 bits firmado extender de un


campo de bits
SBFX<c> <Rd> <Rn> #<LSB> #<Nb> Rd[Nb-1 : 0] Rn[+Nb-1 : LSB
LSB ] Rd[31 : Nb]
Rd[lsb+Nb-1]
Ver UBFX para la versin sin firmar.
74 Assembly Language Programming Instruction Set 74

SXTB 16/32 32 bits firmado extender de un


byte
SXTB<c> <Rd> <Rm> { <rotacin>} rotacin Rd32(Rn)[7 : 0]
Rd[31 : 8]
Rd[7].
Ver UXTB para la versin sin firmar. La rotacin (que es opcional)
puede ser ROR ROR #8, #16 o #24 ROR. Nos permite elegir cul de
los cuatro bytes en el registro para promover.

SXTH 16/32 32 bits firmado ampliar de media


palabra
SXTH<c> <Rd> <Rm> { <rotacin>} Rd32 de rotacin(Rn)[15 : 0]
Rd[31 : 8]
Ver UXTH para la versin sin Rd[15].
firmar
Rotacin (que es opcional) puede ser ROR #8 o #16 ROR ROR o #24.
Nos permite seleccionar los dos bytes consecutivos del registro para ser
promocionado.
UBFX 16/32 Extensin de 32 bits sin signo de
campo de bits
UBFX<c> <Rd> <Rn> #<LSB> #<Nb> Rd[Nb-1 : 0] Rn[+Nb-1 : LSB
LSB ] Rd[31 :
Ver SBFX para la versin firmada. Nb] 0

UXTB 16/32 Ampliar sin signo de 32 bits de un


byte
UXTB<c> <Rd> <Rm> { <rotacin>} rotacin Rd32((Rn)[7 : 0]
Rd[31 : 8] 0
Ver SXTB para la versin
firmada.
Rotacin (que es opcional) puede ser ROR #8 o #16 ROR ROR o #24.
Nos permite seleccionar los dos bytes consecutivos del registro para ser
promocionado.
UXTH 16/32 Ampliar sin signo de 32 bits de la mitad
de la palabra
UXTH<c> <Rd> <Rm> { <rotacin>} rotacin Rd32((Rn)[15 : 0]
Rd[31 : 8] 0
Ver SXTH para la versin
firmada.
Rotacin (que es opcional) puede ser ROR #8 o #16 ROR ROR o #24.
Nos permite seleccionar los dos bytes consecutivos del registro para ser
promocionado.
75 Assembly Language Programming Instruction Set 75

5.4. Instrucciones de transferencia interna

El concepto de la transferencia interna abarca las transferencias que no llame a


ubicaciones de memoria. Por lo tanto, son transferencias entre registros o registrar las
asignaciones con valores de inmediato.

ADR 16/32 Carga de direccin de


cdigo
ADR<c> <Rd> <label> Rd direccin de
Nos permite cargar una direccin en una zona de cdigoetiqueta
mediante
un cambio relativo en el contador de programa (PC, con un mximo
de 4.096). La etiqueta puede corresponder a una zona de piscina
Literal y debe ser local para el mdulo.

MOV 16/32 Transferencia de registro


interno
MOV{S}<c> <Rd> # <const.> Rd const.
MOV{S}<c> <Rd> <Rm> Rd RM
Reemplaza MOVW MOV si const no puede ser codificado en 11
bits. Es posible
Sera conveniente efectuar un mov con un registro de origen
desplazado pero esto es equivalente a la utilizacin directa
de ASR, LSR, LSL, etc.
Por ejemplo: MOV <Rd><Rm>,# ASR asr <n> <Rd><Rm>#<n>.
MOVT 16/32
La asignacin de los 16 bits LSB de un
registro
MOVT<c> <Rd> #<imm16> Rd[16 : 31] imm16
El 16 LSBs permanecen invariables.

Lectura de un registro
La 32
especial
Sra. (Mover a registro
La Sra.<c> <Rn><spec_reg> Rn especial)
spec_reg
Los registros especiales
son:
APSR, XPSR, IPSR, EPSR, PSP, MSP, BASEPRI PRIMASK,
FAULTMASK, CONTROL BASEPRI_MAX y control.
El uso de esta instruccin requiere Cortex-M3 para ser configurados
con un nivel de acceso privilegiado (vase la seccin 2.2).
76 Assembly Language Programming Instruction Set 76

Escribir en un registro
MSR 32
especial
MSR<c> <SPEC_reg><Rn> (Mover al registrarte en Rn
Spec_reg
especial)
Los registros especiales
son:
APSR, XPSR, IPSR, EPSR, PSP, MSP, BASEPRI PRIMASK,
FAULTMASK, CONTROL BASEPRI_MAX y control.
El uso de esta instruccin requiere Cortex-M3 para ser configurados
con un nivel de acceso privilegiado (vase la seccin 2.2).

5.5. Instrucciones de prueba

En su mayor parte, las instrucciones pueden estar vinculados a ciertas


condiciones, es decir una combinacin lgica de las banderas. En el captulo 6, las
diferentes estructuras algortmicas ser explicado, todo basado claramente en la
expresin de la condicin y, en ltima instancia, sobre la programacin de pruebas.
Las instrucciones que se presentan en esta seccin son aquellos que no tienen ningn
resultado distinto del pabelln la modificacin.

Adems sin la asignacin - Modificacin del


CMN 16/32
pabelln
CMN<c> <Rn> # <const.> (Comparar
Banderas test(rn +
negativo)
const)
CMN<c> <Rn> Banderas test(rn +
<Rm>{<Mays>} Rn puede ser el registro
shift(Rm))
SP.

Resta sin asignacin - Modificacin del pabelln


CMP 16/32
(comparar)
CMP<c> <Rn> # <const.> Banderas test(Rn -
CMP<c> <Rn> <Rm>{<Mays>} const ) test(Rn -
Banderas
cambio(Rm))
Rn puede ser el registro
SP.
Esta es la instruccin ms frecuentemente utilizado para
realizar pruebas. De hecho, un b no es directamente
utilizable. Es a diferencia de su equivalente (a - b) 0 porque
banderas N Y Z contendr el resultado.
77 Assembly Language Programming Instruction Set 77

Exclusivo o sin asignacin - Modificacin del


TEQ 32 pabelln
TEQ<c> <Rn> # <const.> Banderas(prueba
test(Rn XOR
const ) de equivalencia)
TEQ<c> <Rn> <Rm>{<Mays>} Banderas test(Rn XOR
Rn puede ser elshift(Rm))
registro SP.

Lgica y sin asignacin - Modificacin del pabelln


TST 16/32
(Test).
TST<c> <Rn> # <const.> Banderas test(Rn y const )
TST<c> <Rn> <Rm>{<Mays>} Banderas test(Rn y shift(Rm))
Rn puede no ser el registro SP.

5.6. Instrucciones de rama

Instrucciones de rama, junto con las instrucciones de la prueba, nos permiten


comprender las diferentes estructuras algortmicas de un programa. Esta es tambin
la manera de llamar a los procedimientos.

Todas las instrucciones estn codificadas en 16 o 32 bits. Para respetar el


principio de la alineacin, la direccin de una instruccin debe ser al menos aun. Sin
embargo, considere el ejemplo 5.1.

EJEMPLO DE LSB 5.1.- La direccin de un salto

LDR , R0=Labe1 ; cargar una direccin...


BX R0 ; ...y saltar a la direccin contenida en R0
...
Etiquet ... ; Rendez-vous punto
a
Observacin de los contenidos de R0 mostrar que el LSB es 1, nos lleva a creer
que el punto de encuentro es en una direccin extraa. Ms sorprendente an, si
utilizamos un depurador para forzar el LSB para ser 0, se iniciar una excepcin de
error de gestin de memoria (vase la seccin 8.2.1).

Esta curiosidad viene de los sucesivos desarrollos del brazo de arquitecturas, y


sobre todo desde la introduccin del pulgar . De hecho es posible hacer algunos
procesadores ARM funcionan tanto con el completo conjunto de brazo de 32 bits o
con la disminucin en el pulgar . Esta tcnica se denomina el interfuncionamiento en
el brazo de la documentacin. El bit[0], entonces, es til en el manejo de estos
interruptores. En el
78 Assembly Language Programming Instruction Set 78

Caso de Cortex-M3, no existe tal cosa, ya que slo el pulgar (y su extensin pulgar2)
existe. Cinco instrucciones, sin embargo, requieren poco[0] a ser 1 para funcionar
correctamente. Estas son las instrucciones BLX, BX, LDR, POP y LDM, las tres ltimas
slo se preocupa cuando se modifique el PC. Durante la ejecucin de esas
instrucciones, y por tanto durante la asignacin del puntero de instruccin, el LSB se
borrar y as la direccin rendezvous ser an.

De nuevo, no hay necesidad de preocuparse; todo es completamente transparente


en la fase de programacin. El ensamblador y el link editor sabr cmo calcular los
mejores valores para producir perfectamente cdigo ejecutable. En la fase de
desarrollo, sin embargo, esta informacin puede ser importante para evitar ser
sorprendido por una diferencia entre la direccin de destino y la direccin real.

B 16/32 Simple Rama


B<c> <label> ETIQUETA DE PC
Equivalente a una simple asignacin del puntero de instrucciones.

BL. 32 Rama con Link


BL<c> <label> LR volver @
PC
El retorno @ es el valor actual de la PC+4 con bit[0]=1. etiqueta

BLX 16 Rama y el intercambio con el enlace


Registrarse
BLX<c> <Rm> LR volver @
PC RM
Este utiliza el mismo principio que
la BL.
La direccin de llamada est contenida en el
registro de RM.
Permite la gestin de tablas de "salto" o punteros a funcin. El
X del medio nemotcnico de divisas,
Pero en ningn caso el Rm recibe el valor previo de la
PC.
BX 16 Rama y el intercambio por
registro
BX<c> <Rm> PC RM
Esta instruccin permite el retorno de procedimiento cuando el
registro
LR. X significa lo mismo como lo hace
en la BLX.
79 Assembly Language Programming Instruction Set 79

CBZ, CBNZ 16 Rama condicional sobre la nulidad de un


registro
CBZ<c> <Rm> <label> PC etiqueta si (Rm =
CBNZ<c> <Rm> <label> 0)PC etiqueta si

Esta instruccin no modifica las banderas y nos(Rm0)


permite llevar a
cabo una rama condicional sin llevar a cabo la prueba anterior.
El salto debe ser "adelante" y limitadas a 126 bytes
(con un mximo de 62 instrucciones).

Las dos instrucciones siguientes permiten la implementacin de estructuras


algortmicas bsicas (estructuras alternativas). Incluso si son especialmente
interesantes en sus dimensiones compactas y su velocidad de ejecucin, todava
tienen un uso limitado, debido a la cantidad de instrucciones admitidos tras una
condicin. En la seccin 6.2, veremos cmo un sistemtico programa modular nos
permite liberarnos de estas limitaciones y procesar en cualquier caso.

Ell 16 Estado y Si...Entonces saltar


a
Se{x{S}}}{z <firstcond> Corrige la ejecucin de los siguientes bloques de
instrucciones
Firstcond determina la condicin para (ese nmero cuatro como
la primera
instruccin mximo).
X,y,z, fija las condiciones para la segunda, tercera y cuarta instrucciones del
bloque. x,y,z son relativos a firstcond con T (entonces = TRUE) o E (otra cosa =
FALSE).
Ser consciente de que las instrucciones del bloque debe tener el
sufijo <c>, que denota la condicin o nos dice que est codificada en
el opuesto.
Puede omitirse pero el ensamblador se insertarn
automticamente
EJEMPLO 5.2.- Ejemplo de uso de instrucciones
Si usted necesita uno ms instrucciones.
CMP R4,R2 ; modificar las banderas
EQ ITTE ; 3 instrucciones
acondicionado TRUE TRUE FALSE
ADDEQ R4,R1 ; la instruccin llevada a
cabo si R4 = R2
LSREQ R2#2 ; la instruccin llevada a cabo si R4 = R2
SUBNE R4,R2 ; la instruccin llevada a cabo si R4 R2
LSR , R4#1 ; la instruccin siempre se llevan a
cabo
CMP R4,R2
IT LT ; => error de montaje
AgregarGE R4,R2 ; el cdigo condiciones son diferentes
80 Assembly Language Programming Instruction Set 80

TBB, TBH 32 Tabla de salto relativo (Byte o semi-word)


TBB<c> [<Rn> <Rm>] PC PC + Rn[ara]
TBH<c> [<Rn> <Rm> LSL #1] PC PC + Rn[shift(Rm)]
Aqu, Rn contiene la direccin de una tabla y rm especifica el ndice en la tabla.
La tabla contiene el nmero de medias palabras que debe ser saltado para
llegar a los casos que se manejan. La tabla contiene un pedazo de salto
informacin relativa
La posicin de la TBB o instruccin TBH utilizado.
EJEMPLO 5.3.- Ejemplo de uso Instrucciones de TBB

Tabla
El DCB 0 ; Primer caso siguiente instruccin TBB
El DCB (caso2-caso1)/2 ; el nmero de bytes a saltar para llegar a caso 2
El DCB (caso3-caso1)/2 ; el nmero de bytes a saltar para llegar a caso 3

ADR R4,la tabla ; la recuperacin de la direccin de la tabla
TBB [R4,R1] ; suponemos que el ndice se almacena en R1
Caso 1 AGREGAR R5, R8 ; Caso 1: adicin
B Finalizar ; equivalente a romper en C
Caso 2 sub- R5, R8 ; en el Caso 2: la sustraccin
B Finalizar ; equivalente a romper en C
Caso 3 SBC R5, R8 ; Caso 3: sustraccin invertida
B Finalizar ; equivalente a romper
en C Finalizar ; Resultado de programa

5.7. Cargar/guardar instrucciones

5.7.1. Simples transferencias

Simples transferencias consisten en el traslado de un byte, una mitad de palabra


(de dos bytes) o una palabra (4 bytes) de memoria para registrar (lectura) o de registro
a memoria (escritura). El cuadro 5.3 resume los mnemnicos para las distintas
transferencias.
81 Assembly Language Programming Instruction Set 81

Tipo de Leer (carga). Escritura


datos (tienda)
Palabra (32 bits) LDR STR
Firmado media palabra (16 LDRSH STRH
bits)
Unsigned media palabra (16 LDRH STRH
bits) Firmado byte (8 bits) LDRSB STRB
Unsigned byte (8 bits) LDRB STRB

Cuadro 5.3. Las teclas aceleradoras para diferentes transferencias

Esta tabla muestra que la lectura distingue entre nmeros firmados y no firmados.
De hecho, como todos los 32 bits de un registro son asignados sistemticamente
durante la carga (la lectura), es necesario que el procesador para saber cmo debe
llenar el 16 (o LDRH LDRSH) o 24 (LDRB o LDRSB) bits ms significativos del
registro. La tcnica de llenado es diferente segn si el nmero representa una cantidad
firmado (cuando decimos firm el ascenso, el bit de signo se copian en el ms
significativo de los bits para ser promovido) o una cantidad sin firmar (unsigned
promocin llena estos bits con ceros). En el escrito, este problema no aparece como
el 8, 16 32 bits del registro se copian tal y como estn y ocupan el mismo espacio
en memoria que ocupan en el registro.

El esquema detallado de mnemnicos a continuacin solo se da por la transferencia


de una palabra (LDR y STR). Los diferentes tipos de sintaxis para otras transferencias
son, en las dimensiones de los datos transferidos, estrictamente idnticas.

LDR Cargar un registro con una palabra de


memoria
LDR<c> <tr> [<Rn> { #<imm>}] RtM32 (Rnimm)
LDR<c> <tr> [<Rn> #<imm>] ! Rn
Rn+imm luego
LDR<c> <tr> [<Rn>] #<imm> RtRtM32
M32(Rn) (Rn)
Entonces Rn
LDR<c> <tr> <label> Rn+imm etiqueta
LDR<c> <tr> [PC, #<imm>] RtM32Rt
(Pcimm)
LDR<c> <tr> [<Rn> <Rm> {LSL,#<Mays>}] RtM32 (Rn+mays(Rm
)) puntero de
Regstrese Rn puede ser el puntero de pila (SP) o el
instrucciones PC.
82 Assembly Language Programming Instruction Set 82

STR Descarga de un registro para una


palabra de memoria
STR<c> <tr> [<Rn> {#<imm>}] M32 (Rnimm)Rt
STR<c> <tr> [<Rn> #<imm>] ! Rn
Rn+imm luego
STR<c> <tr> [<Rn>] #<imm> M32(Rn)Rt
M32 (Rn)
Rtentonces Rn
Regstrese Rn puede ser Rn+imm
el SP.
No hay tal cosa como el escrito relativo al PC (no tiene sentido).

5.7.2. Las transferencias


mltiples

Con una sola instruccin, es posible solicitar la carga (o descarga simultnea,


respectivamente) de varios registros (o, respectivamente, a) una direccin base. Para
ello debemos especificar una lista de registros en un cors, la direccin de la base se
almacena en un registro (acceso indirecto).

REMARK 5.2.- llaves en esta sintaxis, a diferencia de lo que ocurre en el resto de las
instrucciones, no indican una caracterstica opcional. Es la sintaxis requerida para la
lista de registros. Otro, ms imparable, La trampa est en la LDM, STM, y LDMDB
STMDB instrucciones, donde la Rn register se comporta como un puntero, pero no es
necesario ponerlo entre corchetes ([Rn]). Con respecto a la instruccin no es ilgico
(no es posible llenar un registro con el contenido de varios registros), pero para el
programador esto requiere mucha flexibilidad mental.

El registro que contiene la direccin base no puede ser parte de la lista de registros.
Sin embargo, puede ser el SP. Esto es muy til cuando se realizan un contexto
Save/Restore, mientras que la tramitacin de una interrupcin, por ejemplo. El PC
(R15) registro puede ser incluido en la lista, que no es sin consecuencias durante la
carga como esto es equivalente a realizar un salto. Por lo tanto, utilizarse con gran
precaucin.

La 16/32 Carga desde mltiples direcciones


LDM ascendente
La LDM<c> <rk>,{Ri-Rj} Rk M32(Rn + 4 * (k - i) con k = i...j
La LDM<c> <rk>!{Ri-Rj} Rk M32(Rn + 4 * (k - i) con k = i...j
Entonces Rn rn + 4 * (j
Rn apunta a la direccin-de
i)
lectura.
Cuidado: En este caso la ! No significa pre-desplazamiento sino la
modificacin del registro despus de la transferencia y post-incremento.
Esta instruccin tambin utiliza las teclas aceleradoras y LDMIA LDMFD.
83 Assembly Language Programming Instruction Set 83

LDMDB 32 Carga desde mltiples direcciones


descendente
LDMDB<c> <rk>,{Ri-Rj} Rk M32(Rn-4*(k-i+1) con k=i...j
LDMDB<c> <rk>!{Ri-Rj} Rk M32(Rn-4*(k-i+1) con k=i...j
Entonces Rn Rn -j - 4 *
( i)
Salida Rn contiene la primera direccin despus de la zona de
almacenamiento. Por lo tanto, hay un decremento de puntero antes de la
lectura. Esta instruccin est adaptada para la gestin de la pre-
decrementacin pila. Cuidado: En este caso la ! No significa pre-
desplazamiento sino la modificacin del registro despus de la
transferencia y as post-decremento. Esta instruccin tambin utiliza el
nemotcnico LDMEA.

LDRD 32 Carga doble


LDRD<c> <tr> <Rt2>, <Literal> Rt M32(literal)
Rt2 Mliteral
LDRD<c> <tr> <Rt2>, [PC, #<imm>] (32+4)
Rt M32(IMM)
PC+Rt2
LDRD<c> <TR><Rt2>[<Rn>{#<imm>}] MRt
32(PC+imm+4)
M (Rn+imm)
32
Rt2 M32(Rn+imm+4)
LDRD<c> <TR><Rt2>[<Rn>#<imm>] ! Rn
Rn+imm luego
Rt M32(Rn+imm)
LDRD<c> <TR><Rt2>[<Rn>]#<imm> Y Rt2Rt
M32(Rn+imm+4)
M32(Rn+imm)
Rt2 M32(Rn+imm+4)
entonces Rn
Rn+imm
Aqu literal es una etiqueta en la zona de la piscina literal para las
dos primeras formas son, por lo tanto,
equivalente.

STM 16/32 Descarga de mltiples direcciones a


ascendente
STM<c> <rk>,{Ri-Rj} M32(Rn+4*(k-i)Rk con k=i...j
STM<c> <rk>!{Ri-Rj} M32(Rn+4*(k-i)Rk con k=i...j
Entonces Rn rn + 4 * (j
- i) lugar la
Aqu Rn seala a la direccin donde tendr
escritura. Cuidado: En este caso la ! No significa pre-displacementbut
modificacin del registro despus de la transferencia y sopost-incremento.
Este
La instruccin tambin utilizael mnemnicos STMIA y
STMEA.
84 Assembly Language Programming Instruction Set 84

STMDB 32 Mltiples direcciones de descarga


descendente
STMDB<c> <rk>,{Ri-Rj} M32(Rn-4*(k-i+1)Rk con k=i...j
STMDB<c> <rk>!{Ri-Rj} M32(Rn-4*(k-i+1)Rk con k=i...j
Entonces Rn Rn -j - 4 *
En esta instruccin, Rn puntos por encima de la( direccin
i) donde tendr
lugar la escritura. Cuidado: En este caso la ! No significa pre-
desplazamiento sino la modificacin del registro despus de la
transferencia y as post-decremento. Esta instruccin tambin utiliza el
nemotcnico STMFD.

Std 32 Descarga doble


Std<c> <TR><Rt2>[<Rn>{#<imm>}] M32 (IMM)Rn+R
T
Std<c> <TR><Rt2>[<Rn>#<imm>] ! M32 (Rn+imm+4)Rt2
Rn
Rn+imm luego
M32(IMM)Rn+RT
Std<c> <TR><Rt2>[<Rn>]#<imm> Y M32(Rn+imm+4)Rt2
M32 (IMM)Rn+R
T
M32 (Rn+imm+4)Rt2
entonces Rn
Rn+imm
5.7.3. El acceso a la pila del sistema

De hecho es posible para lograr el acceso de lectura/escritura a la pila del


sistema (pre-decrementacin evolucin) siguiendo las instrucciones y STM LDMDB.
Hay dos teclas especficas (en la totalidad del conjunto de idiomas) para llevar a cabo
este tipo de transferencia. No obstante, cabe sealar que el cdigo generado ser a
menudo idnticos.

POP 16/32 La carga de la pila del sistema


POP<c> {Ri-Rj} Rk M32(SP+4*(k-i))con k=i...j
Luego SP SP + 4 * (j -
Esto es equivalente ai)la LDM SP !, {R -i
Rj }. Es posible desapilar PC pero no
LR.
85 Assembly Language Programming Instruction Set 85

PUSH 16/32 Para guardar en la pila del


sistema
Empujar<c> {Ri- M32(SP-4*(k-i+1)Rk con k=i...j
Rj} Luego SP SP -j - 4 * (
i) SP !, {R -R }.
Esto es equivalente a STM i j
Es posible apilar LR pero no en PC.

5.8. "Sistema" instrucciones y otros

Instrucciones descritas aqu como "sistema" las instrucciones que nos permitan
actuar sobre el estado del procesador. Los "otros" se incluyen instrucciones utilizando
un hipottico coprocesador o gestionar la depuracin de secuencias. En cualquier caso,
stas slo son tiles en un enfoque detallado para el funcionamiento del ncleo Cortex-
M3 y, por consiguiente, quedan fuera del alcance de este libro. Una lista simple se da
aqu. El usuario avanzado encontrar completa informacin en los manuales de
referencia DEL BRAZO [06a, brazo 06c].

Sistema...
#<BKPT imm8> Pide una excepcin de
CPD,CPD2 .... depuracin
Lanza una instruccin sobre un
CLRX Suprimecoprocesador
la exclusividad del procesador.
Cambia el estado de Cortex-M3
CPS <efecto><banderas>
modificando y FAULTMASK PRIMASK
DBG><c # <option> Lanza una solicitud Trace o
DMB<c> # <option> Debug
La instalacin de una barrera de
acceso a la memoria
La instalacin de una barrera de
Osd<c> # <option>
acceso a la memoria
ISB<c> <opc.> con la sincronizacin
Vaca la canalizacin del
LDC, LDC2 ... procesador
Leer (memoria de) un coprocesador
LDRBT,LDRHT,LDRT registrarse
Escriba (sin firma) de memoria en modo sin
LDRSBT,LDRSHT privilegios
Leer (firmado) de memoria en modo sin
STRBT,STRHT,STRT privilegios
Escriba (sin firma) de memoria en modo sin
STRSBT,STRSHT privilegios
(Firmado) Escritura de la memoria en modo
LDREX,LDREXB,LDREXH sin privilegios
Leer (unsigned) de memoria en modo
STREX,STREXB,STREXH exclusivo.
Escriba (sin firma) de memoria en modo
De MCR, MCR2 exclusivo. Escribir un coprocesador
registrarse
86 Assembly Language Programming Instruction Set 86

MCRR, MCRR2 Escribir un (64-bit) registro de


MRC, MRC2 coprocesadorLeer un coprocesador
MRRC, MRRC2 Leer unregistrarse
registro de coprocesador
PLD PLDW de 64 bits Datos de precarga
PLI Instrucciones de
SEV precarga
Enviar una seal (situacin en
, STC STC2 Multiprocessor)
Leer (memoria) de un coprocesador
O SVC (SWI) registrarse Generar una llamada del
WFE supervisor
Esperar un evento
WFI Espere una
Rendimiento interrupcin
Enviar la seal (multitarea)
Captulo 6

Algoritmos y estructuras de
datos.

6.1. Diagrama de flujo del algoritmo versus

El lenguaje ensamblador utiliza etiquetas y saltos, que pueden ser o no condicional.


Esto conduce naturalmente a una visin geogrfica de un programa, donde
representamos el plan de ruta (mapa de ruta) de las instrucciones en forma de un
diagrama de flujo, acordado con smbolos para representar el condicional de
desviacin (switches), entre otros. Tal uso de diagramas de flujo fue abandonado hace
mucho tiempo, sin embargo, en favor de escribir algoritmos estructurados por diversas
razones. Aqu estn algunos de ellos:
- el diseo y mantenimiento de un diagrama de flujo es laborioso.
- la depuracin de programas tambin es laborioso: si hay un problema en la
ejecucin de una instruccin, no es evidente la ruta que tomamos en el diagrama de
flujo para llegar a este punto.
- es muy difcil probar slo una parte de un programa;
- tambin es muy difcil extraer parte de un programa a partir de un diagrama de
flujo con el fin de reutilizarlo en un programa posterior.

Por tanto, preferimos alentar un anlisis de rbol, conocido como anlisis modular
en la que cada programa est formado exclusivamente por una sucesin de elementos
celulares, genricamente llamados mdulos, cada mdulo en s una serie de sub-
mdulos, etc. en el nivel ms bsico, llegamos a la idea de un lenguaje estructurado
compuesto de instrucciones que, al igual que los mdulos, slo tiene un punto de
entrada y un punto de salida. De esta manera es posible obtener lenguaje estructurado
cuando se programa correctamente.
88 Assembly Language Programming Algorithmic and Data Structures 88

En lenguaje ensamblador, en el mejor de los casos, hemos incorporado estos


conceptos: el programa puede ser escrito a diferentes archivos (denominados
"mdulos" en la jerga usada por assemblyists), que constituyen lo que se conoce como
la modularidad externo. Cada archivo se compone de procedimientos, que se llaman
subrutinas, etc. Esto se conoce como modularidad interior. Cada mdulo o
procedimiento representa un pedazo del programa: debe poder ser probado por
separado, y para ser reutilizada posteriormente en otro programa. En el nivel ms
profundo de esta estructura de rbol ideal, nos encontramos con la
instruccin. Observando que cada mdulo tiene slo un punto de entrada y un punto
de salida, la instruccin debe tambin tienen solo una entrada y una salida. Hay un
truco con el lenguaje ensamblador, sin embargo, puesto que el lenguaje ensamblador
no es un lenguaje estructurado! Algunas instrucciones, tales como instrucciones
condicionales, por ejemplo, disponen de dos salidas. A pesar de ello, nos acercamos
a la programacin en lenguaje ensamblador de una manera estructurada: tenemos todo
el problema con el llamado aprendizaje sistemtico. El nivel ms bajo de los mdulos
se describi por primera vez con un algoritmo estructurado. Luego, para cada
instruccin estructurada en el algoritmo, nos sistemticamente transcribir en lenguaje
ensamblador segn un modelo preparado de antemano. Cada instruccin estructurada
a continuacin corresponde a un bloque compuesto de lneas de instrucciones
en lenguaje ensamblador. Este bloque slo tiene un punto de entrada (la primera
instruccin) y un punto de salida. Si no hay etiquetas en este bloque, debemos
considerarlos especfico para este bloque, y que son inaccesibles a otros bloques
externos. El nico rtulo accesible al mundo exterior es la etiqueta de entrada, que
est publicada en la primera instruccin del bloque sellado. En este captulo, vamos
a mostrar cmo cada instruccin estructurada puede transformarse en un bloque de
instrucciones en lenguaje ensamblador. Para cada bloque de instrucciones
presentadas, usaremos las etiquetas de entrada y salida_point_Point para mostrar
los puntos de entrada y salida de la cuadra. Las instrucciones en lenguaje algortmico
estructurado se utilizan las siguientes convenciones:
- cond representa una condicin booleana.
- No(cond) es la negacin lgica de cond;
- Tratamiento es una secuencia de instrucciones que se ejecutan.
- dato variable es un entero.

Cabe sealar que, en aras de la legibilidad de un programa en lenguaje


ensamblador, se recomienda encarecidamente que cada bloque contiene un mximo
de alrededor de
10 lneas. El tratamiento puede constar de varias instrucciones simples, o bien llamar
a procedimientos. Debemos tener en cuenta que los nombres de las etiquetas han sido
escogidos para corresponder lo ms estrechamente posible a aquellos que aparecen en
los algoritmos, pero tambin debemos ser conscientes de que estos nombres o este
mtodo de elegir las etiquetas en un programa real sera una muy mala idea.

REMARK 6.1.- En este captulo presentaremos las diferentes estructuras algortmicas,


omitiendo deliberadamente una instruccin peculiares del brazo: assembler
(interrupcin) (es decir, la opcin de estado la mayora de las instrucciones
aritmticas y lgicas). Este
89 Assembly Language Programming Algorithmic and Data Structures 89

Eleccin est motivada por el hecho de que la instruccin slo puede acondicionar un
mximo de cuatro instrucciones, por lo que no es una respuesta definitiva al problema.
Lo que es ms, no nos permiten abordar los problemas estructurales, que son
necesarias para avanzar hacia un mtodo sistemtico de la programacin. No
obstante, es cierto que el uso de la instruccin puede ser una respuesta eficaz que es
para poner en marcha rpida y eficiente en trminos de tamao de cdigo y por lo
tanto no debe ser olvidado completamente.

6.2. Estructuras
alternativas

6.2.1. Simple (o reducir) alternativa

La alternativa simple decide si procede o no realizar el tratamiento, por lo que no


es acompaado por una clusula else:
Si (cond)
Entonces el tratamiento
End If

El bloque de instrucciones traducir esta estructura algortmica utiliza una de las


cuatro instrucciones de prueba (vase la seccin 5.5), de los cuales el nico objetivo
es posicionar las banderas. El acondicionado salta que siga uno de estos ensayos, a
continuacin, utilice el estado de las banderas para efectuar los saltos (si procede).
Como es ms directamente comprensible en este contexto, la aplicacin de los
ejemplos presentados ms adelante se basar en la utilizacin de la CMP (comparar)
instruccin, seguido inmediatamente por un salto condicional.

Para empezar , echemos una versin genrica de la alternativa simple (vase


Ejemplo 6.1).

Leyendo esta lista reducida conduce a la formulacin de varias observaciones:


- No usamos(cond) en lugar de cond: este mtodo es comn a todos los lenguajes
ensambladores. El salto condicional slo tiene lugar si el complemento de cond es true.
As, esta instruccin se establece la posibilidad de impedir que el tratamiento que se
est llevando a cabo;
- Las etiquetas entry_point y si marca la misma instruccin, el CMP;
- la etiqueta Exit_punto marca la primera instruccin del bloque siguiente.

En este ejemplo, las etiquetas si y Lab_entonces tienen una funcin informativa y


didctica. Esta es una manera indirecta de comentario en el cdigo. Slo la
etiqueta Exit_punto es fundamental, porque se le hace referencia en un salto.
90 Assembly Language Programming Algorithmic and Data Structures 90

EJEMPLO 6.1.- versin genrica de la alternativa simple

Entrada_Point

Si Val_CMP,val_2

B Exit_point ; corresponden a no(cond)

Lab_luego ... Instrucciones ;

... ; para

... ; el tratamiento

Exit_Point ...

Unejemplo PPLIED 6.1.- Tome el valor absoluto de una firma (32-bit) entero
contenida en el registro R1:

Si entero < 0
Luego -Integer Integer
End If

Estudio de la condicin: cond es "<", es decir, firmado LT, as que no(cond) es "
firmado", o GE (firmado es mayor que o igual a). Podemos codificar esta como
sigue:

EJEMPLO 6.2.- El ejemplo de la alternativa simple

Entrada_Point

CMP, R1#0

BGE Exit_point ; comparacin con 0

Lab_luego NEG ; R1 R1-R1

Exit_punto ...

6.2.2. Alternativa completa

La alternativa completa introduce una clusula else en el sencillo formulario


presentado en el Ejemplo 6.2:
91 Assembly Language Programming Algorithmic and Data Structures 91

Si
Entonces el tratamiento_luego
(cond)
Entonces el tratamiento_else
Else

End If

Esto demuestra el caso del trato exclusivo. Para representar esta estructura
algortmica, podemos utilizar no(cond) tan bien como hemos visto por la alternativa
simple, cond.

Como generalmente es preferible para la legibilidad del cdigo


a utilizar no(cond), esto es lo que vamos a hacer aqu. En efecto, con esta eleccin
el bloque de tratamiento tratamiento_luego se coloca antes del tratamiento_ bloque
Else, que hace que la lectura, junto con el algoritmo ms sencillo.

EJEMPLO 6.3.- La versin genrica de la alternativa completa


Entrada_Poi
nt
Si Val_CMP,val_2
B Exit_point ; corresponden a no(cond)
Lab_luego ... Instrucciones ;
... ; para
... ; Tratamiento_luego
B Exit_point ; es necesario para evitar el
bloque else
Lab_Else ... Instrucciones ;
... ; para
... ; Tratamiento_else
Exit_punto ...

Este bloque de lenguaje ensamblador utiliza una rama condicional para


proporcionar la posibilidad de saltar el tratamiento_luego para alcanzar el
tratamiento_Else. Nota la imprescindible presencia del salto incondicional al final
del tratamiento_entonces a fin de que el programa no realizar tratamiento_Else!

Unejemplo PPLIED 6.2.- utilizamos un mtodo de visualizacin que toma la direccin


del mensaje (es decir, el conjunto de bytes que corresponde a los cdigos ASCII de los
caracteres), en el registro R0, que se muestra como un argumento. Por lo tanto, es
posible crear dos mensajes que nos permiten mostrar si un nmero entero almacenado
en R4 y codificada en 16
92 Assembly Language Programming Algorithmic and Data Structures 92

Bits es estrictamente negativo o positivo. La discriminacin se hace entonces por


una estructura IfElse:

Si entero < 0
A continuacin, R0 @ mensaje negativo
Otra cosa
A continuacin, R0 @ mensaje positivo.
End If

Pantalla(R0)

Una posible codificacin de este algoritmo proporciona:

EJEMPLO 6.4.- ejemplo de alternativa completa

;*************************************************************
; Seccin de datos
; Zona*************************************************************
MyDATA, datos, ALIGN=0
;*************************************************************
Message_Pos "DCB es estrictamente positivo, 10,13,0 "
Neg_Mensaje "DCB es negativo o nulo", 10,13,0

;*************************************************************
; seccin de cdigo
;*************************************************************
MyCode, cdigo de rea, readonly, ALIGN=2
;*************************************************************
...
Entrada_Point
Lab_Si SXHT R3,R4 ; 32 bits firmado
ampliar
CMP, R3#0 ; comparacin en 0
BGT, Lab_else
Lab_luego LDR, R0=Mensaje_Neg ; R0 @ Message_Neg
B Exit_Point ; la evitacin del
bloque Else
Lab_else LDR, R0=Mensaje_Pos ; R0 @ Message_Pos.
Exit_Point BL DispStr ; la pantalla Llamada
a procedimiento
...
93 Assembly Language Programming Algorithmic and Data Structures 93

Pasando por el registro R3, la extensin del entero firmado para ser probado en
32 bits podran evitarse usando un 16-bit shift derecha o mediante pruebas
(TST instrucciones)
Slo los bits firmado (peso 15) del entero.

REMARK 6.2.- La codificacin anterior pone de relieve el hecho de que el trabajo en


un datum codificada en un byte o semi-palabra rpidamente pueden volverse tedioso
porque la unidad lgica y de Arithemtic (ALU) de Cortex-M3 slo funciona en
palabras de 32 bits.

6.2.3. Caso especial de la alternativa

Muy a menudo podemos reducir una alternativa completa, lo que es ms agotador


para programar, una simple alternativa que es ms fcil volver a leer. Esta
simplificacin se basa en una eleccin a priori que se realiza en la alternativa (por
ejemplo, el otro caso). Llevamos a cabo esta eleccin por adelantado y prueba (la
alternativa simple) si ha sido confirmado. Si este no es el caso, efectuar la doble
alternativa. Esta prctica supone que las dos alternativas son mutuamente excluyentes
(que es normalmente el caso en una alternativa completa) y que la realizacin de una
de las alternativas modifica ni el examen ni los elementos necesarios para la ejecucin
de los bloques.

Volvamos al ejemplo anterior. Puede ser transformada como este:

A continuacin, R0 @ mensaje positivo.


Si entero < 0
A continuacin, R0 @ mensaje negativo
End If
Pantalla(R0)

La codificacin es luego modificado como este:

EJEMPLO 6.5.- La simplificacin de una alternativa completa a una simple alternativa


...
Entrada_Poi
nt
LDR, R0=Mensaje_Pos ; R0 @ Message_Pos.

Si SXHT Lab_R3,R4 ; 32 bits firmado ampliar


CMP, R3#0 ; comparacin en 0
BGT,Exit_Point
Lab_luego LDR, R0=Mensaje_Neg ; R0 @ Message_Neg
94 Assembly Language Programming Algorithmic and Data Structures 94

Exit_Point
BL DispStr ; llamada al procedimiento
de visualizacin
...

6.2.4. Eleccin mltiple

Eleccin mltiple corresponde a la estructura algortmica segn. Si es llamado caso


(como en Ada), interruptor (como en C), o incluso sobregoto (como en Basic), que
permite al usuario programar un tratamiento basado en el valor de un entero o
enumerado variable. Nos limitaremos a valores enteros.

Switch Case (variable)


Valor_0 :Tratamiento
valor_0_1 :
Tratamiento _1 valor_2
: Tratamiento _2 (...)
Otro valor: Tratamiento _default
Interruptor de extremo caso

El intuitivo (y no ptima) mtodo de programacin esta estructura en lenguaje


ensamblador consta de una cadena de estructuras IfThen. El algoritmo se convierte
en:

Si variable= valor_0
Entonces el tratamiento_0
Else If variable = valor_1
Entonces el tratamiento_1
Else If variable = valor_2
Entonces el
tratamiento_2
(etc.).
Else default_tratamiento
95 Assembly Language Programming Algorithmic and Data Structures 95

Por razones de claridad y sin perder la generalidad, en el lenguaje ensamblador


aplicacin presentados, cada tratamiento ser sometido a una llamada a
procedimiento. Tambin vamos a limitarnos a tres valores de la seleccin.

EJEMPLO 6.6.- estructura Switch Case tratada como una cadena de estructuras IfThen

Entry_punto ...
MOV R4,ref_variable
Lab_Switch CMP, R4#value_0
BNE Ver_Uno ; cond = EQ, por lo que no(cond) = NE BL tratamiento_0
B Exit_point ; final de
tratamiento => Salir ! Ver_One CMP,
R4#value_1
BNE,VER_2
Tratamiento BL_1
B Exit_point ; final de
tratamiento => Salir ! Ver_DOS CMP,
R4#value_2
BNE,ver_Default
Tratamiento BL_2
B Exit_point ; final de tratamiento => Salir !
Ver_Default
BL default_tratamiento
Exit_punto ...

El salto incondicional Punto B_Exit que finaliza cada clusula Then nos
permite salir de la estructura Switch Case: el equivalente en C es la instruccin break.

Una secuencia de estructuras idnticas es largo y tedioso para escribir si ms de


unos valores que han sido incluidos en la estructura Switch Case. Tambin es
incmodo para modificar si otro caso tiene que ser agregado. Lo que es ms, la
seleccin del tiempo de ejecucin depende de la posicin del valor en la lista.

Un segundo mtodo, que es ms adecuado para el lenguaje ensamblador, consiste


en la utilizacin de tablas de salto. Una primera versin de este tipo de estructura
corresponde al uso de la TBB (bytes) o sucursal de tabla (Tabla Sucursal Halfword
TBH) instrucciones. Un ejemplo de este tipo de utilizacin se dio durante la
explicacin de estas instrucciones (vase la seccin 5.6). El uso de TBB o TBH implica
que el salto la tabla es una tabla de salto relativo con respecto a una direccin de
referencia y, por tanto, rpidamente pueden volverse muy limitante.
96 Assembly Language Programming Algorithmic and Data Structures 96

Una versin ligeramente ms genrico (es decir, directamente extrapolables para


otro conjunto de instrucciones que no tiene un equivalente de TBB o TBH) se
presenta a continuacin. Esta segunda versin se basa en una tabla de salto absoluta:
el tratamiento del caso de direcciones se almacena directamente en la tabla. De
antemano, cada tratamiento debe ser marcado con una etiqueta, que de preferencia es
encapsulado dentro de un procedimiento. La direccin de cada procedimiento de
tratamiento se coloca en una tabla (en C, parece que hay una tabla de punteros a
funcin). Utilizamos el valor de la variable de seleccin, el nmero entero, como un
ndice en esta tabla. Esto significa que el valor 0 debe provocar la ejecucin
del tratamiento_0, 1 debe provocar la ejecucin del tratamiento_1, etc. Por lo
tanto, es suficiente para llamar al procedimiento indirectamente, como se muestra
Ejemplo 6.7, donde simplemente tenemos que considerar los valores de seleccin de
0 a 6, y donde slo los valores 0, 2 y 6 estn sujetos a un tratamiento especfico:

EJEMPLO 6.7.- estructura Switch Case usando una tabla de salto

MyCode, cdigo de rea, readonly, ALIGN=2


;*************************************************************
Entrada_Point
LDR, R9 = saltar la tabla ; R9 puntero en jump_table
LDR[R2, R9, R6,LSL #2] BLX
R2
Exit_punto ...
;*************************************************************
Procedimientos de tratamiento ;
;*************************************************************
Tratamiento_ PROC
0
...
BX LR ;
volve
Tratamiento_ ENDP
r
0
Tratamiento_ PROC
2
...
BX LR ;
volve
Tratamiento_ ENDP
r
2
Tratamiento_ PROC
6
...
BX LR ;
volve
Tratamiento_ ENDP
r
6

Tratamiento_Default PROC
97 Assembly Language Programming Algorithmic and Data Structures 97

...
BX LR ; Volver al llamador
Tratamiento_Default ENDP
;************************************************************
*
; Seccin de datos
;
Zona*****************************************
******************** MyData, datos, ALIGN=0,
READONLY
;****************************************************
********* jump_Tabla_0 Tratamiento DCD,
tratamiento_Default ; de 0 y 1.
Tratamiento de la DCD_2, el tratamiento_Default ; para 2 y 3
Tratamiento de la DCD_Default_Default Tratamiento ; para 4 y 5
Tratamiento de la DCD_6 ; para 6
;*************************************************************

En este ejemplo, se asume que el registro R6 contiene el valor de seleccin


(integer) entre 0 y 6, resultante de una prueba anterior. La tabla se rellena con
elementos que son las direcciones de los procedimientos (en cada caso, esto es, en
realidad, la direccin de la primera instruccin del procedimiento). El salto se efecta
mediante la BLX (rama con el enlace y el intercambio) instruccin, donde R2 contiene
la direccin del procedimiento que se debe alcanzar. Todo lo que queda es entender
cmo esta direccin y, por lo tanto, la instruccin de asignacin : R2 R2,
LDR[R9,R6,LSL #2], se calcula. Esto implica la lectura mediante direccionamiento
indirecto e indexado: R2 jump_tabla[R6 * 4].

El Jump_tabla direccin base es almacenada previamente en R9: este es indirecto


(uso de corchetes). El ndice se almacena en R6, pero como indirecto trabaja
directamente en las direcciones de memoria y como cada direccin de procedimiento
ocupa 32 bits de memoria de los elementos de la tabla ocupan cada uno de cuatro
bytes. El ndice se multiplica por cuatro para tener esto en cuenta. Esta
multiplicacin por cuatro es fcilmente codificada por un desplazamiento a la
izquierda de 2 bits, que corresponde al uso de LSL#2 como un operador adicional
aplicado a R6.

El mecanismo adoptado, por lo tanto, utiliza el doble de direccionamiento


indirecto: R9 apunta a un elemento, el cual apunta a un procedimiento! Las ventajas de
esta solucin son la sencillez de su estructura y una constante de tiempo de seleccin.
No obstante, sta tiene dos inconvenientes: en primer lugar es necesario para obtener
un valor de seleccin en forma de un entero natural; en segundo lugar, es necesario
asegurar que el valor de seleccin pertenece al intervalo de los valores pronosticados.
Esto requiere la inclusin de la estructura Switch Case en una alternativa completa:
98 Assembly Language Programming Algorithmic and Data Structures 98

Si la seleccin_valor >6 (sin firmar)

A continuacin, default_tratamiento
Switch Case Else (variable)

final Switch Case

End If

El Jump_tabla se coloca en una seccin de datos donde el acceso est restringido


a la Lectura (opcin READONLY). La estructura que aqu se presenta es
estrictamente esttico y no es la intencin de que el procedimiento de cambio de
direcciones. Por lo tanto, parece prudente para garantizar la durabilidad de estos datos
mediante el bloqueo de todos los accesos (incluso y sobre todo accidentales) para
escribir. Una formulacin dinmica de tal estructura, donde el salto tabla puede
cambiar durante la ejecucin del programa, sigue siendo posible, en cuyo caso la
opcin READONLY sera eliminada.

6.3. Estructuras iterativas

Estructuras iterativas, en contraposicin a las estructuras selectivas, son bloques


de instrucciones que estn pensados para ser ejecutado varias veces. El nmero de
iteraciones es condicionada (esta condicin puede ser el nmero de iteraciones a
alcanzar, como en el caso de un bucle For) y este nmero puede ser cero.

6.3.1. El bucle repeathasta

La forma genrica de esta estructura es:

Repita
Tratamiento

Hasta (cond)

En esta estructura, la evaluacin de la condicin sigue un salto condicional


efectuada tras el tratamiento, lo que da la siguiente forma general:
99 Assembly Language Programming Algorithmic and Data Structures 99

EJEMPLO 6.8.- forma genrica de la estructura.Hasta repetir.

Entrada_Point

Repetir ... Instrucciones ;


... ; de
... ; Tratamiento
CMP Val_1,val_2
B Repetir ; corresponden a no(cond)
Exit_punto ...

Una vez ms, la decisin de salto es establecido por la (no)cond. Podemos superar
esto, sin embargo, expresar el algoritmo como una repeticinAunque. La condicin
de salto se convierte entonces en la misma condicin que el texto. Lo que es importante
en la identificacin de esta estructura es que la prueba se realiza al final de la
estructura. Por lo tanto, el tratamiento se lleva a cabo al menos una vez.

Unejemplo PPLIED 6.3.- El regreso de una zona de memoria compuesta de palabras


de media (16 bits) a cero, donde sabemos la direccin inicial y la direccin final.
Vamos a suponer que hay al menos un elemento en la tabla. El algoritmo presentado a
continuacin se utiliza el concepto de un puntero y utiliza el C de smbolos en la
explicacin. As, el operador @ permite la recuperacin de la direccin y el
operador *(Ptr) nos permite ver el contenido de la direccin apuntada por el
puntero PTR:

Ptr @Table
Ptr_end @End_Table

Repita
*(Ptr) 0

Ptr Ptr + 2

Hasta (PTR PTR_final)

En el siguiente cdigo propuesto, suponemos que el registro R0 corresponde al


puntero PTR, y el registro R5 a PTR_End:
100 Assembly Language Algorithmic and Data Structures 100
Programming

EJEMPLO 6.9.- Repetir...Hasta estructura

;*************************************************************
; Seccin de datos
;
Zona***********************************************
************** MyData, datos, ALIGN=0
;********************************************************
***** tabla rellenen 24,0xff,2 ; el llenado de 12 palabras de media
; inicializado para 255
End_Table ; simple etiqueta para
; Marca el final de la tabla
;*************************************************************
; seccin de cdigo
;********************************************************
***** MyCode, cdigo de rea, readonly, ALIGN=2
;********************************************************
***** LDR, R0 = Tabla ; carga de PTR
LDR R5, =End_Table ; carga de PTR_end
MOV R2#0 ; variable local para limpieza
Entrada_Point
Repita STRH R2,[R0] ; supresin de corriente
; valor apuntado
Agregar R0,#2 ; el incremento del puntero
CMP R0,R5 ; prueba de no(cond)
BLT Repetir ; Saltar si tabla_end no alcanzado
Exit_punto ...
;*************************************************************

El cdigo sugerido puede ser optimizado. En efecto un solo indirecto se utiliza para
llevar a cabo la eliminacin. Por lo tanto, supone un incremento "manual" del puntero,
pero el conjunto de instrucciones tiene un post-desplazados el modo de
direccionamiento. Las dos primeras lneas de la repeticinhasta que la estructura
puede ser sustituido por una sola lnea que integra el incremento del puntero: STRH
R2,[R0],#2.

Tomemos otro ejemplo. Esto implica cambiar el signo de los primeros 10


elementos de una tabla de bytes. El nmero de bucles es, por lo tanto, fija y conocida
de antemano.
101 Assembly Language Algorithmic and Data Structures 101
Programming

Ptr @Table
contador 10
Repita
*(Ptr) -(*(Ptr)
PTR Ptr + 1
CONTADOR contador - 1
Hasta 0 (contador)

Un clsico de codificacin en lenguaje ensamblador (utilizamos R11 para el contador


y R0 para
Ptr) proporciona:

EJEMPLO 6.10.- El segundo ejemplo de una estructura de repeticin hasta...

;*************************************************************
; Seccin de datos
; Zona************************************************************* MyData,
datos, ALIGN=0
; Tabla***************************************************
********** DCB 12,0x23,-3,24 ; reserva de 12 bytes
El DCB -56,0xAB,0,0 ; inicializado con diversos valores.
1,2,5,9 DCB
Llenar 10,0XE4,1 ; seguido de 10 bytes
; inicializado a 0XE4
;*************************************************************
; seccin de cdigo
;*************************************************************
MyCode, cdigo de rea, readonly, ALIGN=2
LDR, R0 = Tabla ; carga de PTR
MOV R11, #10 ; la inicializacin del contador
Entrada_Point
Repita LDRB R2,[R0] ; Recuperacin del valor sealado actual
NEG R2,R2 ; signo inversin
STRB R2,[R0],#1 ; volver a escribir con post-desplazados
SUBS R11,#1 ; Decremento del contador
; con asignacin de bandera
102 Assembly Language Algorithmic and Data Structures 102
Programming

BGT Repetir ; Saltar si menos de 10 tratamientos


Exit_punto ...
;*************************************************************

Esta codificacin utiliza post-incremento. Una versin equivalente sera usar


direccionamiento indirecto con la indexacin en la lectura y escritura:

EJEMPLO 6.11.- Una versin modificada del ejemplo 6.10

...
LDR, R0 = Tabla ; carga de PTR
MOV R11, #9 ; la inicializacin del contador
Entrada_Point
Repita LDRB[R2, R0, R11] ; Recuperacin del valor sealado actual
NEG R2,R2 ; signo inversin
STRB[R2, R0, R11] ; volver a escribir con la indexacin
SUBS R11,#1 ; Decremento del contador
; con asignacin de bandera
BGE Repetir ; Saltar si menos de 10 tratamientos
Exit_punto ...

En esta segunda versin, el orden de lectura/escritura de la tabla es el inverso:


Recuperamos el dcimo primer elemento. Esto implica que el contador debe cubrir
los valores de 9 a 0 inclusive. La inicializacin del contador y la condicin de salto
son, por tanto, modificarse en este sentido (el salto condicionado pasa
de BGT A BGE).

6.3.2. Mientras que el bucle


Do...

Esta estructura es bastante similar a la anterior. La principal diferencia radica en el


hecho de que la prueba se realiza antes de comenzar el tratamiento. Existe, por
tanto, dejar el paso obligado en el bloque de tratamiento.

La forma genrica
es:

Mientras (cond) el
tratamien
to
Fin mientras
103 Assembly Language Algorithmic and Data Structures 103
Programming

Es posible construir una hasta que bucle utilizando no(cond). En este caso,
expresando el algoritmo como hasta (cond) es posible construir general
codificacin con la misma prueba de lenguaje ensamblador que se establece en el
algoritmo.

EJEMPLO 6.12.- forma genrica de la estructura mientras que hacer...

Entrada_Point
Lab_mientras CMP Val_1,val_2
B Exit_point ; corresponden a no(cond)
... Instrucciones ;
... ; de
... ; Tratamiento
B Lab_mientras
Exit_punto ...

El salto incondicional al final del tratamiento conduce siempre a la evaluacin de


la comparacin.

Un ejemplo PPLIED 6.4.- En el ejemplo 6.4, el programador llama a


un procedimiento DispStr para mostrar un mensaje. Si nos fijamos en los mensajes,
se compone de un conjunto de caracteres ASCII y terminan con "10", "13" y "0".

"10" y "13" corresponden a los caracteres de retorno de carro y salto de lnea.


Ellos nos permiten (en el clsico terminal alfanumrico) para mover el cursor al
principio de la lnea siguiente. El "0" indica el final de la cadena. Por lo tanto,
podemos esperar que el algoritmo de este procedimiento de visualizacin busca este
carcter de terminal de la siguiente manera:

Si bien ((current_Caract.= *(Ptr) NUL )


PostChar(current_caract.)
PTR PTR +1
Hasta el final

Una solucin de codificacin para este algoritmo es dada aqu:


104 Assembly Language Algorithmic and Data Structures 104
Programming

EJEMPLO 6.13.- Un rato...No estructura

;****************************************
;* Procedimiento de visualizacin de una cadena
;* de entrada : puntero en la cadena : R0
;* Salir : ninguno
;* Utilice el procedimiento DispChar
;*******************************
********* DispStr PROC
Empujar
{LR}
Empujar {R1}

Mientras LDRB Lab_R1,[R0],#1 ; Recuperacin del valor sealado actual


CMP, R1#0
BEQ End_Disp ; prueba de no(cond)
BL DispChar ; llamada al procedimiento
DispChar
B Lab_Mientras ; Loop

End_Disp POP {R1}


POP {PC}

ENDP

En esta codificacin, el registro R1 acta como una variable local para el


almacenamiento del carcter actual. Este recurso a un registro general tan pronto como
queremos llevar a cabo la ms pequea de las operaciones en una variable de la
memoria (aqu una comparacin simple) es el costo del uso de cargar/guardar la
arquitectura. Veremos que este registro es guardado en la pila del sistema
(pulsar sobre la entrada y salida - POP en el funcionamiento de las pilas se detalla en
Seccin 6.5.6), que permite al programador que quiere utilizar esta rutina para ignorar
lo que ocurre en ella (l/ella debe saber dnde l/ella tiene que especificar la direccin
de cadena).

REMARK 6.3.- ahorro sistemtico de los registros alterados por un procedimiento es


una opcin estratgica. En efecto, lo que nos permite asegurar nuestro cdigo en la
medida en que el "procedimiento de llamada" slo tiene que respetar las reglas de un
posible paso de argumentos y no prev ninguna salvaguarda de registros antes de la
llamada. Hay un costo, sin embargo, en trminos de uso de memoria y velocidad de
ejecucin, ya que requiere una serie de Push/POP para su aplicacin.
105 Assembly Language Algorithmic and Data Structures 105
Programming

Otro registro es guardado: el enlace Registrar (LR). De hecho, esta rutina tambin
exige un procedimiento (BL Dispchar) este registro ser borrado por la nueva
llamada. Por lo tanto, es necesario para salvar a nosotros mismos. Esto sucede en
el empuje inicial. En el otro lado no hay equivalente simtricos, es decir, POP LR.
Tampoco existe un BX LR. Estas dos lneas son sustituidos por POP PC, que nos
permite llevar a cabo la restauracin y el retorno al mismo tiempo. Volveremos a este
punto especfico en el Captulo 9.

Una segunda codificacin se propone a continuacin. Para esta versin, se han


introducido dos modificaciones importantes con el objetivo de optimizar el cdigo y
utilizando los mejores puntos de la instruccin set.

La prueba es reportada al final del bucle. A tal fin podrn realizarse al comienzo
del bucle, un salto incondicional comienza la estructura. La ventaja de esto es que
podemos obtener comenzando con una codificacin que no prueba cond (cond). Esto
se traduce en una ligera prdida de legibilidad, ya que la prueba se coloca despus de
la estructura, incluso si se lleva a cabo antes de ella.

Los dos stackings estn comprimidos en una sola instruccin por empujar {R1,LR}.
Simtricamente los dos unstackings son sustituidos por POP{R1,PC}. Ser consciente
del orden en el que se especifique la lista de registros!

EJEMPLO 6.14.- La segunda versin del mientras....No ejemplo

DispStr PROC
Empujar {R1,LR}
B Lab_Cond

Lab_mientras BL DispChar ; llamada al procedimiento


DispChar
Lab_Cond LDRB R1,[R0],#1 ; Recuperacin del valor sealado actual
CMP, R1#0
BNE Lab_Mientras ; Prueba de(cond) : saltar si R1 0

End_Disp POP {R1,PC}


ENDP

6.3.3. El bucle para

En algortmica, se suele utilizar el bucle For en forma genrica:


106 Assembly Language Algorithmic and Data Structures 106
Programming

Para Var va desde Val0 y Val1, Incremento k


Tratamiento
Para finales

Dicha estructura se puede reducir fcilmente a un tiempo Hacer estructura:

Var Val0
Mientras (Var1) No Val
Tratamiento
var var + K
Hasta el final

Este formulario se utiliza, por ejemplo, 6.10.

REMARK 6.4.- el bucle For existen? En algortmica, sin duda alguna! En lenguaje
ensamblador, esto es menos evidente porque aqu, en cualquier caso, se transforma en
un tiempobucle Do. Hay otros procesadores (los de Intel o de Freescale, por
ejemplo), sin embargo, que tener una instruccin integrada que reduce un registro y
saltar a una etiqueta si el decremento no da un resultado cero, permitiendo la
codificacin directa de una estructura.

6.4 Condiciones
compuesto.

Las estructuras y los ejemplos que hemos tratado hasta ahora siempre han tenido
las condiciones individuales. En la prctica, a menudo es necesario cambiar a
condiciones compuestas, como por ejemplo:

Si ( (Nmero > 0) y cond_End = False) ) y luego...

Vamos a sealar de paso que en esta situacin, la instruccin (que deberamos


recordar corresponde a poner una instruccin bajo una condicin directa) ya no es
suficiente.

Es imposible (e intil) para hacer frente a todas las formas posibles de


combinaciones, pero en el dominio de la tcnica para el manejo de condiciones
booleanas compuesta de dos trminos o
107 Assembly Language Algorithmic and Data Structures 107
Programming

Factores y extrapolando a un mayor nmero de trminos, todo es posible y, por


ltimo, con un mnimo de rigor, muy fcil.

6.4.1. Alternativa con Y

Una combinacin corresponde a:

Si (cond_A y cond_B)
Entonces el tratamiento
End If

En lenguaje ensamblador, separamos la evaluacin de cond_A de


Cond_B, y se vincula la decisin como sigue:

Si (cond_A)
Entonces si (cond_B)
Entonces el tratamiento
End If
End If

REMARK 6.5.- Esto nos lleva de vuelta a lo que llamamos un progresivo y en C:


Si cond_A es falsa, la segunda condicin no se evala. En un lenguaje de alto nivel, esto
puede causar contratiempos para el programador, por lo que en algunos lenguajes como
Ada, evaluaciones de tipo Boolean se completa sin utilizar una opcin de compilacin
o un operador ad hoc.

El siguiente es el bloque de instrucciones correspondientes a esta

estructura: Ejemplos de 6,15.- genrico y condicin compuesta

Entrada_Point
Lab_Si CMP var,val_A ; Evaluacin de cond_A
B Exit_Point ; corresponden a no(cond_A)
Lab_luego_A CMP var,val_B ; Evaluacin de cond_B
B Exit_Point ; corresponden a no(cond_B)
108 Assembly Language Algorithmic and Data Structures 108
Programming

Luego_Lab_B ... Instrucciones ;


... ; de
... ; Tratamiento
Exit_Point ...

6.4.2. Iteracin con Y

Veamos el caso de repeticinhasta el caso utilizando un compuesto condicin


booleana.

Repita
Tratamiento
Hasta (cond_A y cond_B)

El siguiente es el marco del bloque correspondiente en lenguaje ensamblador:

EJEMPLO 6.16.- Repetirhasta el bucle con una condicin compuesta

Entrada_Point
Repetir las instrucciones ;
... ; de
... ; Tratamiento
CMP var,val_; Evaluacin de cond_A
B Exit_point ; corresponden a no(cond_A) CMP
var,val_B ; Evaluacin de cond_B
B Exit_point ; corresponden a no(cond_B) B Repeat ;
Loop en repetir la etiqueta
Exit_punto ...

El cdigo puede optimizarse mediante la compresin de las dos ltimas pruebas:


109 Assembly Language Algorithmic and Data Structures 109
Programming

EJEMPLO 6.17.- versin modificada de la repeticinhasta con un bucle y


Condicin compuesta

...

CMP var,val_; Evaluacin de cond_A

B Exit_point ; corresponden a no(cond_A)

CMP var,val_B ; Evaluacin de cond_B

B Repetir ; corresponden a cond_B

; Loop en repetir si cond_B

REMARK 6.6.- la condicin de salida del bucle puede, en este caso, ser tan bien
expresado como mientras [no(cond_A) o no(cond_B)].

6.4.3. Alternativa con o

Composicin con un OR lgico:

Si (cond_A O cond_B)
entonces el
tratamiento
End If

Tambin puede ser expresada como una secuencia de evaluaciones:

Si (cond_A)
Entonces el tratamiento
Else If (cond_B)
entonces el
tratamiento
End If

Codificacin directa y literal de este algoritmo es bastante ineficiente, ya que


requerira la duplicacin del tratamiento instrucciones. Una traduccin ms adaptable
en lenguaje ensamblador consiste en la utilizacin de la evaluacin
de cond_A primera, luego de que no(cond_B).
110 Assembly Language Algorithmic and Data Structures 110
Programming

EJEMPLO 6.18.- genricos o condicin compuesta

Entrada_Point
Lab_Si CMP var,val_; Evaluacin de cond_A
B Tratar ; corresponden a (cond_A)
Lab_Else CMP var,val_B ; Evaluacin de cond_B
B Exit_point ; corresponden a no(cond_B)
Tratamient
o
... Instrucciones ;
... ; de
... ; Tratamiento

Exit_Point

En este caso, la segunda prueba no se llev a cabo sistemticamente.


Si cond_a es verificada, cond_B no se evala.

REMARK 6.7.- debemos tener en cuenta que con esta composicin es directo y natural
que probamos cond_A y no su opuesto. Este esfuerzo no durar mucho, ya que
no(cond_B) viene detrs tan naturalmente.

6.4.4. Iteracin con o

Como ha sido demostrado para la composicin, y veamos cmo una o


Composicin encaja en
una repeticinhasta loop:

Repita
Tratamiento

Hasta (cond_A O cond_B)

Como en el caso anterior, utilizamos cond_A con no(cond_B). El siguiente es el


marco del bloque correspondiente en lenguaje ensamblador:
111 Assembly Language Algorithmic and Data Structures 111
Programming

EJEMPLO 6.19.- Repetir...hasta el bucle con un estado compuesto o

Entrada_Point
Repetir ... Instrucciones ;
... ; de
... ; Tratamiento
CMP ; Evaluacin de cond_A
var,val_B Exit_ ; corresponden a (cond_A)
Pointvar,val_B
CMP ; Evaluacin de cond_B
B Repetir ; corresponden a no(cond_B)
Exit_Point

REMARK 6.8.- lgebra booleana nos muestra que hasta (cond_A O cond_B) = mientras
[(NO(cond_A) y no(cond_B)].

6.5 Estructura de datos.

El lenguaje ensamblador de un procesador de 32 bits nos permite explotar


fcilmente datos en uno, dos o cuatro bytes considerado como componentes de las
estructuras elementales: registros, tablas, colas y pilas. El lenguaje ensamblador, a
diferencia de los lenguajes de alto nivel, no utilice una directiva de ensamblado que
nos permite directamente declarar o definir uno de estas estructuras. Por lo tanto,
corresponder a los programadores a construir explcitamente con la ayuda de las
directivas de reserva de espacio o la reserva de directivas de inicializacin ,
Relleno , DCW DCB y DCD (al menos por lo que se refiere a los datos permanentes,
porque los datos dinmicos creados durante la ejecucin de un programa que plantea
otros problemas). Si los datos deben ser escritos o ledos en ms de cuatro bytes, el
tratamiento de los datos representa un reto adicional para el programador (que
trabajan en mltiples precision).

6.5.1. Tabla de una dimensin

Tambin se denomina un vector, una tabla se compone de datos con idntica


naturaleza coloca en posiciones de memoria consecutivas. Para datos sencillos, byte,
semi-word o word, podemos fcilmente explorar esa tabla utilizando modos de
direccionamiento indirecto. Es suficiente para asignar la Rn registrarse con la direccin
de la tabla y modificar este valor sealador antes ([Rn,#<imm>]!) o despus de
acceso ([Rn,#<imm>]!).

Para acceder directamente a un dato en la tabla (acceso directo), tambin es posible


utilizar un ndice almacenado en un registro auxiliar de RM ({Rn, Rm, LSL #
<Mays>}). El ndice de RM
112 Assembly Language Algorithmic and Data Structures 112
Programming

Contendr el nmero del elemento que se desea alcanzar y el shift izquierda


por LSL nos permite calcular automticamente el desplazamiento que se agrega a la
direccin base para alcanzar este elemento (LSL#1 para 16 bits y tablas LSL#2 para 32
bits tablas, etc).

REMARK 6.9.- El lenguaje ensamblador proporciona al programador la libertad total


en relacin con el mtodo de colocacin de elementos en la memoria. El mtodo
descrito anteriormente es el arco clsico y simple, pero el algoritmo usado a veces
puede ser ms fcil de programar si los datos estn ordenados en orden inverso en la
memoria (elemento de ndice ms alto en la direccin ms baja) o incluso si ellos se
confunden en una forma ms sutil, por ejemplo, de acuerdo a la secuencia "primero -
ltima - segunda - segundo al ltimo - etc"! La eficacia es la principal motivacin para
escribir en lenguaje ensamblador
- eficiencia durante la ejecucin, pero tambin durante la re-lectura de programas, por
lo que es muy til para comentar de forma inteligente estas soluciones "exticos".

6.5.2. Las tablas de dimensiones


mltiples

Una tabla que tiene mltiples dimensiones, que se designan con el


smbolo Tab, deben ser ordenados en la memoria en forma lineal. Tomemos el ejemplo
de una tabla de dos dimensiones, con Nb_col columnas y Nd_Row filas. Es posible que
los elementos de la ficha para organizarse fila por fila o columna por columna. Es
usual (y esto simplifica las cosas cuando pensamos en trminos de almacenamiento)
para decir que el ndice Ind_fila de la fila es de entre 0 y Nb_row-1, y de la columna
Ind_col es entre 0 y Ind_col-1. Para llegar a la ficha Elemento (Ind_Row, Ind_Col),
debemos primero calcular lo que llamamos el ndice lineal : Relative_Lugar . Este
ndice puede ser utilizada en el direccionamiento indirecto con ndice, como en el caso
de la tabla unidimensional. Aqu tenemos:
- Fila por fila:
Relative_Lugar = Ind_Row x Nb_col + Ind_col

- Columna por columna disposicin:


Relative_Lugar = Ind_Row + Ind_col x Nb_Row

Permtanos ilustrarlo con el caso de una matriz de tres filas y cuatro columnas:

Un0, Un0, Un0, Un0,


0 1 2 3
Un1, Un1, Un1, Un1,
0 1 2 3
Un,2, Un,2, Un,2, Un,2,
0 1 2 3
113 Assembly Language Algorithmic and Data Structures 113
Programming

La fila por fila arreglo se almacenan en orden creciente de direccin como sigue:

Un0, Un0, Un0, Un0, Un1, Un1, Un1, Un1, Un2, Un2, Un2, Un2,
0 1 2 3 0 1 2 3 0 1 2 3
Direccin base

La columna por columna acuerdo tambin sern almacenados en orden creciente


de direccin, como sigue:

Un0, Un1,0 Un2,0 Un0,1 Un1,1 Un2,1 Un0,2 Un1,2 Un2,2 Un0,3 Un1,3 Un2,
0 3
Direccin
base

6.5.3. Inscripcin

Utilizamos el trmino registro o registro (estructura en C y grabar en Ada) para un


conjunto de campos de datos consecutivos unidos bajo un nombre simblico comn y
organizado a partir de una direccin determinada. En general, estos datos son de
diferentes tipos, en contraposicin a las tablas, que estn compuestas exclusivamente
de datos del mismo tipo. El programador lugares diversos campos en posiciones de
memoria consecutivas. El primer byte o la primera palabra de estos campos es
fcilmente accesible mediante el direccionamiento indirecto con
desplazamiento [rn+#imm8], donde la Rn registrar puntos al inicio de la inscripcin,
es decir, contiene la direccin ms baja, y donde la imm8 es positivo, calculada en
bytes. El primer byte del primer campo corresponde al desplazamiento del cero. Si
consideramos un registro con una parte variante (normalmente un conjunto de
caracteres), debemos reservar el espacio de memoria necesario para la variante ms
grande. Por lo tanto, es interesante que el campo variante es el ltimo en el registro.

6.5.4. Tabla adimensional, cadena de caracteres

El tamao de una tabla no puede ser conocido durante la grabacin de un programa


o cambiado durante la ejecucin. Por lo tanto, es ms conveniente que sea capaz de
crear una asignacin dinmica de memoria: la tabla se crea durante la ejecucin y el
lugar que ocupa en la memoria reservada (asignados) en ese momento. Esta tcnica es
posible directamente si usamos un sistema operativo capaz de asignar una determinada
cantidad de memoria.

En un entorno de software ms restringido, donde el programador es el nico


patrn a bordo y debe gestionar todo a l o a ella, esto se vuelve ms difcil, pero no
imposible. Una tcnica comn para hacerlo consta de
114 Assembly Language Algorithmic and Data Structures 114
Programming

Uso temporal del espacio (el momento de la ejecucin del procedimiento) en la pila
del sistema; esta zona de almacenamiento se perdern cuando el programa regrese al
procedimiento.

Fuera del caso de asignacin dinmica, las variables se dice que es esttico: llaman
a una tabla permanente, la reserva se hace con antelacin (Espacio, relleno, etc.) y el
tamao del espacio de memoria reservado es fijo. Por lo tanto, debemos reservar un
lugar en la memoria que nos permitir recibir la tabla ms grande que podramos
esperar.

Un segundo problema que aparece aqu. Dado que la tabla es de tamao variable,
de qu tamao es por el momento nos interesa? Hay dos formas de mostrar el tamao
de una tabla:
- En primer lugar, creamos una estructura donde el primer campo contiene el
tamao actual de la tabla.
- La segunda es la propia tabla.

En el segundo mtodo, que marca el final de la tabla con un elemento que se ha


acordado un valor especial. Por ejemplo, es bastante habitual que el carcter NULL
(valor = 0, que no debe confundirse con el carcter '0', que tiene el valor 0x30) al final
de una cadena de caracteres.

REMARK 6.10.- debemos recordar para reservar un lugar de memoria para el elemento
de marcador en el extremo de la mesa, con el fin de n elementos utilizando una tabla
necesitamos espacio para n+1 elementos.

6.5.5. Cola

Una cola es una FIFO (primero en entrar, primero en salir) estructura de datos.
Los elementos de la cola, que generalmente son todos del mismo tipo, se colocan en
posiciones contiguas en la memoria. Para gestionar la cola, usamos los dos
registros, Rt y Rq, donde Rt apunta a la cabeza - el primer elemento de la cola - y Rq a
la posicin libre que sigue al ltimo elemento de la cola. La absorcin se realizan a la
cabeza de la cola y adiciones al final. Para elementos de 8, 16 o 32 bits, utilizamos el
post-desplazados el modo de direccionamiento para aadir ({Rq]#<imm>) y retirar
([Rt]#<imm>) elementos.

La desventaja de esa cola es que solo crece hacia la creciente direcciones como se
utiliza. Esto significa que se producen con frecuencia una cola circular direccin
limitando el mximo que puede alcanzarse. Tratando de ir ms all de esto implica el
retorno de la direccin actual del menor valor esperado. La posicin de la cola vara
entre estos dos extremos direcciones durante la ejecucin.
115 Assembly Language Algorithmic and Data Structures 115
Programming

Cuando se aade un elemento: si la cola puntero alcanza el puntero de cabeza, la


cola est llena y no puede aceptar ms adiciones. Si durante la extraccin de un puntero
de cabeza alcanza el puntero de la cola, la cola est vaca y no hay ms eliminaciones
son posibles (vase la figura 6.1).

Top

Agregar
La ltima
escritura
En la cola.
CI
Un

A
continuaci
n, lea
En la cola.

Retirar

Parte inferior

Los datos de
superficie

Figura 6.1. Una cola de 32 bits que crece al aumentar las direcciones

6.5.6. Pila

Una pila es un LIFO (ltimo en entrar, primero en salir) estructura. Los datos estn
ordenados consecutivamente en la memoria durante el apilamiento. Son unstacked en
el orden inverso a su orden de apilamiento: el ltimo puesto ser el primer eliminado.
Un nico puntero Rp es suficiente para administrar una pila. Podemos distinguir entre
dos modos de administracin de la pila:
116 Assembly Language Algorithmic and Data Structures 116
Programming

- la direccin de aumentar la pila:


- ascendente: escritura sucesivas se realiza para aumentar direcciones,
- descendente: escritura sucesivas se realiza para disminuir las direcciones;
- gestin de puntero de pila evolucin:
- antes y despus de la lectura de la Escritura: el puntero de pila apunta al
ltimo elemento escrito,
- antes y despus de la lectura de la Escritura: el puntero de pila apunta al
siguiente elemento libre.

Parte
inferior

La ltima
escritura en
la pila

Agregar
Prim
Retirar er
lugar
"libre"
Top

Los datos de
superficie

Figura 6.2. 32 bits (descendente) Pila completa


117 Assembly Language Algorithmic and Data Structures 117
Programming

En la arquitectura Cortex-M3, un mecanismo de pila LIFO existe en el hardware.


Es administrado por el puntero de pila (SP, consulte Seccin 2.2.2). Esta pila, pila,
llamado el sistema por defecto es descendente y con pre-decremento en la escritura
(tambin conocida como una pila Full-Descending), consulte la Figura 6.2.

Tenga cuidado de no unalign una pila destinados a recibir las palabras (o medias
palabras, respectivamente). La direccin contenida en el registro debe ser doblemente
(respectivamente por separado), incluso, es decir, terminando con dos
(respectivamente, 1) cero! Esta es la razn por la que no se recomienda construir una
pila mixta donde apila bytes, palabras y palabras medio indiscriminadamente.

Colas y pilas de que los elementos no son bytes ni medias palabras ni las palabras
son el ms delicado para administrar. Es necesario calcular cambios analgico similar
a las que hemos visto en el caso de tablas. Una tcnica ms ventajosa a menudo
consiste en aadir un nivel de direccionamiento indirecto mediante la creacin de colas
o pilas consistente de las direcciones (referencias) de elementos. La posicin y el
tamao de los elementos son entonces sin importancia real.
Captulo 7

Modularidad
interior

El concepto de un procedimiento, una secuencia de instrucciones pueden ser


llamados como una subrutina, que ha sido presentado en la seccin 3.3.5. En este
captulo, veremos cmo utilizar esta construccin sintctica elemental para escribir
correcta y fcil utilizar subrutinas, aplicando los principios de la programacin
modular. Vamos a ver cmo implementar el paso de argumentos a una subrutina y
cmo crear variables locales.

7.1. Detallando el concepto de procedimiento

7.1.1. Simple llamada

Un procedimiento es un conjunto de instrucciones diseadas para proporcionar un


servicio en particular, por lo general, que termina con la instruccin BX LR. El
procedimiento, que puede ser llamado por una rama y BL (Link) instruccin, se coloca
en el procedimiento de llamada. Esta instruccin se guarda la direccin de retorno (que
vamos a denotar @ret. de ahora en adelante) mediante el enlace Registrar (LR) para
almacenar el valor del puntero de instrucciones (tambin llamado el contador de
programa, PC) que contiene la direccin de la instruccin siguiente de la rama, y luego
salta a la primera instruccin del procedimiento llamado. Al final del procedimiento
de ejecucin, el BX LR instruccin restaura el valor de PC original por cargar el
contenido de la LR y la ejecucin se reanuda en la direccin tras la BL. Ejemplo 7.1
ilustra este principio de una simple llamada a un procedimiento.

7.1.2. Llamadas anidadas

Durante una llamada, la direccin de retorno se almacena en un registro. Si el


llamado procedimiento de s mismo hace una llamada a un procedimiento, el
mecanismo de llamada se borrar automticamente el
120 Assembly Language Programming Internal Modularity 120

El contenido actual de la LR para poder almacenar la nueva direccin de retorno. Si no


se hace nada ms, la direccin de remite del primer nivel de llamadas se pierde
definitivamente y el procedimiento ya no tiene ninguna manera de volver al lugar de
donde procede.

Este problema es bastante tpico en el brazo el lenguaje ensamblador. De hecho, la


inmensa mayora de los diseadores han integrado directamente esta posibilidad de
llamadas anidadas en su eleccin de la arquitectura. As, la direccin de retorno, en
lugar de almacenarse en un registro, se coloca en la pila del sistema de conformidad
con el ltimo en entrar, primero en salir (LIFO) Evolution. Durante el regreso, si la
pila del sistema ha sido correctamente administrados durante el procedimiento, el
programador ser capaz de recuperar la direccin de retorno que es apuntado por
el puntero de pila (SP). El anidamiento de sucesivas llamadas a procedimientos en
consecuencia conduce a sucesivos apilados en la pila del sistema.

En este entendimiento, es suficiente con hacer lo mismo manualmente en


nuestros procedimientos. De hecho, como en el ejemplo 6.13, por apilar (PUSH) el
registro LR a partir de la entrada en el procedimiento, el programador hace que el
valor de LR para ser salvos. En el momento de retorno, recuperamos esta direccin
mediante la lectura de la pila (POP) y, a continuacin, puede efectuar la devolucin
del procedimiento utilizando el BX LR instruccin.

Con esta opcin, la arquitectura de hardware de ARM provee la posibilidad de


llamar a un procedimiento sin el uso de un ciclo de lectura/escritura en la pila del
sistema. Esto presupone la ausencia de llamadas anidadas, pero permite ahorrar
tiempo en el caso de una simple llamada.

EJEMPLO 7.1.- Llamada a un


procedimiento simple

Los princi PROC


...
BL Recurso ; LR @ret
; luego PC
apelacin (salto) Back_all ... ; la
instruccin siguiente
... ; @ret = Back_all
...
ENDP princi
;- - - - - - - - - - - - - - - - - - - - - - - - -
Apelacin PROC
...
BX LR ; PC ENDP
LR Appe al.
121 Assembly Language Programming Internal Modularity 121

7.1.3. "Hilo Rojo" ejemplo

En este captulo, vamos a confiar en un simple pero suficiente, por ejemplo: un


procedimiento cuya funcin es extraer un mximo de dos nmeros enteros de 32 bits
sin signo. En todas las variantes de las soluciones que hemos presentado para este
ejemplo, los datos utilizados sern dos variables almacenadas en las direcciones
denominada ValOne y ValTwo. Los resultados se colocan en la direccin Maxi.

Aqu est una primera versin del procedimiento, titulado MaxVer1. Se accede
directamente a los datos que necesita.

Esta versin de codificar el problema propuesto es deliberadamente "codiciosos"


en trminos de registro use; una solucin ms econmica podra simplemente utilizar
dos registros. Esta ganancia en trminos de tiempo de procesamiento o tamao de
cdigo? En trminos de tamao de cdigo, no. En trminos de ahorro de tiempo de
procesamiento de los registros depende del nmero de registros ponga en la lista
(aproximadamente dos ciclos de reloj por registrar para cada pulsacin y cada POP.
Una ganancia de tiempo pueden esperarse si queremos minimizar el nmero de
registros utilizados (y por tanto el nmero de registros que se guardan) al aplicar una
solucin ms econmica.

EJEMPLO 7.2.- investigacin en el mximo - completar la versin inicial

;*************************************************************
; Seccin de datos
; Zona************************************************************* MyData,
datos, ALIGN=2
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ValOne DCD
345
0DCD ValTwo xABF
Maxi espacio 4
;*************************************************************
; seccin de cdigo
;*************************************************************
MyCode, cdigo de rea, readonly, ALIGN=2
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Procedimiento principal
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Principales PROC
BL MaxVer1 ; llamada al procedimiento
ENDP
122 Assembly Language Programming Internal Modularity 122

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Procedimiento que investiga el mximo
; argumentos pasados : ninguno
; variables globales : ValOne, ValTwo, Maxi
; se utilizan registros: R0, R1, R2, R4
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MaxVer1
PROC
Empujar {R0-R4} ; Guardar los registros modificados
LDR R0=ValOne ; Carga de los
LDR R1,[R0] ; Primer valor
LDR R3=ValTwo ; Carga de los
LDR R2,[R3] ; Segundo valor
CMP R1,R2
BHS Bon ; Si ValOne < ValTwo ...
Cambiar MOV R1,R2 ; ... A
continuacin, exchange
Buena LDR R4= Maxi ; Almacenamiento en Maxi
STR R1,[R4] ; El resultado contenida en R1
POP {R0-R4} ; Restaurar registros guardados
BX LR ; Volver
Infinito B infinito ; Fin del programa
ENDP

REMARK 7.1.- En los ejemplos presentados, los registros utilizados sistemticamente


son guardadas en el inicio del procedimiento y restaurada a finales del mismo. Esta
prctica, como ya hemos mencionado (vase la seccin 6.3.2) permite el uso de estos
procedimientos sin hacer demasiadas preguntas. Poner en una biblioteca, que
fcilmente pueden ser reutilizados sin temor a los efectos secundarios, es decir,
cambiar el ambiente de trabajo del procesador mediante la ejecucin del
procedimiento.

Hay dos excepciones a esta regla:


- La primera excepcin, como veremos ms adelante, se refiere a los
registros usados para pasar argumentos. En este caso, el usuario debe administrar el
contenido de los registros con el fin de utilizar el procedimiento, ahorrando as
ellos se vuelve intil o incluso contraproducente.
- La segunda excepcin es una necesidad imperiosa para obtener el espacio de
memoria o la unidad central de procesamiento (CPU) de tiempo para el procedimiento.

En este caso, todo est muy bien, pero debemos tener en cuenta que un programa
que se cuelga tambin pierde mucho tiempo!
123 Assembly Language Programming Internal Modularity 123

7.2. Argumentos del procedimiento

7.2.1. Utilidad de argumentos

Desde el punto de vista del programa llamante, el MaxVer1 procedimiento cambia


el valor del resultado en la Maxi direccin utilizando los valores registrados
en ValOne y ValTwo. Como esta escrito, tal procedimiento es poco satisfactoria,
porque es necesario dar los datos con nombres especficos, lo cual hace imposible
reutilizar el procedimiento en otro programa, a menos que siempre utilizan los mismos
nombres para los datos.

Asimismo, en la programacin modular, es recomendable que evitemos


directamente el uso de variables globales. Esto es posible gracias a la utilizacin de
los argumentos de llamada explcita. La subrutina se vuelve entonces fcilmente
reutilizable si sigue las reglas convencionales para pasar argumentos.

7.2.2. Argumentos por valor y por referencia

Cada argumento puede ser pasados por valor o por referencia. Si se pasa por valor,
una copia de los datos que se proporcionan a los llamados por el procedimiento de
llamada, por lo que su posible modificacin por sta no afecta a la original: la
modificacin sigue siendo local a la subrutina llamada. Cuando un argumento es
pasado por referencia, nos proporciona la direccin a la subrutina que, mediante
engao, posiblemente podra cambiar el valor de los datos en esa direccin.

No tiene lenguaje ensamblador instrucciones para llamar a una subrutina que


incorporen el concepto de argumento, y el BL instrucciones para Cortex-M3 no es una
excepcin; por lo tanto, plantea la cuestin de por qu mecanismos es posible
proporcionar un procedimiento con los valores o las direcciones relativas de los
argumentos. Bsicamente, hay dos tcnicas, pero ambos pueden ser reducidas a la
misma idea bsica: los argumentos son colocados segn un orden acordado en una
determinada regin de la memoria.

7.2.3. Pasar argumentos por registros generales

Registros generales proporcionan un primer sencillo, rpido y efectivo mtodo de


pasar argumentos. Los valores de los argumentos o sus direcciones (Referencias) se
colocan en el acta de registros, y el procedimiento puede ser utilizado inmediatamente.

7.2.3.1. Pasar argumentos por valor


En nuestro ejemplo, tenemos tres argumentos para considerar: los dos pedazos de
datos de entrada, y el resultado en la salida. Aqu est una primera modificacin del
ejemplo (MaxVer2)
124 Assembly Language Programming Internal Modularity 124

Cuando la entrada de dos argumentos son pasados por valor y el valor del resultado
es devuelto. En la presentacin de estos ejemplos, slo las piezas modificadas sern
reescritas; las declaraciones de secciones, reservas, etc., son completamente
idnticos.

EJEMPLO 7.3.- investigacin en el mximo: pasando por registro y por valor

...
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Principales PROC
LDR, R0=ValOne ; carga del
LDR R1,[R0] ; Primer valor
LDR, R3=ValTwo ; carga del
LDR R2,[R3] ; segundo value
BL MaxVer2 ; llamada al
procedimiento LDR, R4= Maxi ;
escrito el resultado STR
R1,[R4] ; contenida en R1
Infinito infinito B ; Fin del programa
ENDP
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MaxVer2
PROC
CMP R1,R2
BHS Bueno ; si ValOne < ValTwo ... Intercambio MOV R1,R2 ; ... Se
convierte en el buen max ValTwo BX LR ; Volver
ENDP

En esta versin, no hay PUSH/POP en absoluto. De hecho, el procedimiento slo


utiliza los registros para pasar argumentos, para guardarlos es intil.

Observe en este ejemplo las ventajas de pasar argumentos: la


(MaxVer2) procedimiento pasa a ser capaz de llevar a cabo la bsqueda mxima para
cualquier par de nmeros enteros de 32 bits, siempre que estn colocados en los
registros R1 y R2. Podramos aislar el (MaxVer2) el procedimiento en otro mdulo: el
alcance de los datos almacenados en las
direcciones VarOne y VarTwo estara limitado al programa de llamadas, lo cual
correspondera al refuerzo de la localizacin de estos recursos. Esto significa que los
datos mencionados por VarOne, VarTwo y Maxi pertenecen nicamente al
procedimiento de llamada, mientras que en el ejemplo anterior, fueron compartidos
por el llamante y el llamado. Si analizamos este ejemplo, podemos ver que el
procedimiento proporciona el programa que realiza la llamada con el valor del
resultado a travs del registro R1. Este procedimiento se comporta
125 Assembly Language Programming Internal Modularity 125

Como una funcin en un lenguaje de alto nivel, tales como ANSI C, para que el
prototipado sera:

Long int Ver2 Max (long int, long int arg1 arg2);

Y el uso, con las tres previamente declarado enteros largos sera:

Maxi = MaxVer2 (VarOne, VarTwo);

De hecho, la asignacin del valor del resultado es llevada a cabo por el programa
de llamadas, exactamente como en el programa en lenguaje ensamblador.

Los compiladores suelen utilizar pasando por registro porque es ms sencillo y ms directo
(y tan rpido).

REMARK 7.2.- Cuando queremos llamar a una rutina escrito en lenguaje ensamblador
de un programa desarrollado en C, es necesario conocer las convenciones del paso de
argumentos que el compilador usa. Por ejemplo, el brazo de RealView compilador
utiliza registros R0 a R3 para pasar hasta cuatro argumentos de entrada. El retorno se
llev a cabo sistemticamente por el registro R0 (complementado con R1 en el caso
de devolucin de un doble codificada en 8 bytes). Si el paso de argumentos por
registro ya no es posible, por ejemplo, si hay ms de cuatro argumentos de entrada, el
compilador finaliza el proceso utilizando pasando por pila del sistema.

7.2.3.2. Pasar argumentos por


referencia
Veamos otra posibilidad: esta vez, los tres se proporcionan argumentos por
referencia. Por el direccionamiento indirecto (MaxVer3) procedimiento almacena los
resultados en la asignacin de la memoria.

EJEMPLO 7.4.- investigacin en el mximo: pasando por registro y por referencia

...
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Principales PROC
LDR, R0=ValOne ; Pasaring de la @ del primer argumento LDR,
R3=ValTwo ; pasando del @ del segundo argumento LDR,
R4= Maxi ; pasando del @ argumento de la salida.
BL MaxVer3 ; llamada al procedimiento
Infinito infinito B ; Fin del programa
126 Assembly Language Programming Internal Modularity 126

ENDP
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MaxVer3 PROC
Empujar {R1-R2} ; Save la registros modificado
LDR R1,[R0] ; lea el primer argumento
LDR R2,[R3] Leer ; segundo argumento
CMP R1,R2
BHS buena ; Si ValOne < ValTwo ...
Intercambio MOV R1,R2 ; ... ValTwo pasa a ser
el mx.
Buena STR R1,[R4] ; Store el resultado contenida en R1
POP {R1-R2} ; restaurar los registros
guardados
BX LR ; Volver
ENDP

Cabe sealar que el argumento es pasado de salida en la entrada. Esta paradoja se


explica por el hecho de que cargamos el procedimiento por almacenar el resultado. Por
lo tanto, es necesario proporcionar a esta direccin (en la entrada). Es bastante comn
para un argumento pasado por referencia para ser utilizado en la entrada y la salida.
El argumento puede tomar el valor recibido en la entrada y asignar un nuevo valor a
cambio.

La analoga en C dara a los prototipos:

Void MaxVer3 (long int *arg2, long int *Arg3);

Y el uso como:

MaxVer3 (&VarOne, &VarTwo, &Maxi);

7.2.4. Pasar argumentos por una pila

El nmero de registros est limitado, nuevos argumentos riesgo borrar anteriores


como llamadas de procedimientos anidados. Cuando volvamos al procedimiento de
llamada, existe el riesgo de que este procedimiento ya no tendr la totalidad o parte
de sus argumentos de llamada. Por lo tanto, es necesario utilizar la pila del sistema
para hacer la necesaria salva. A partir de esta declaracin, resulta natural utilizar
directamente un sistema LIFO (pila o montn) estructura para almacenar los distintos
argumentos de componentes del procedimiento que se ejecutar.
127 Assembly Language Programming Internal Modularity 127

REMARK 7.3.- Si el programador est preparado para definir una subrutina que
requieran ms de 10 argumentos (por lo que hay ms de 10 registros para pasar
argumentos utilizando slo el registro tcnica), sera bastante razonable para l o ella
a considerar la posibilidad de reestructurar el programa o los datos a fin de desarrollar
una nueva organizacin basada en simples funciones de bloque.

En realidad el problema surge durante las llamadas anidadas (recursin, por


ejemplo) cuando sea necesario para salvar la sucesin de pasar argumentos a descender
a travs de los diferentes niveles de llamada. El problema de la prdida de estos
argumentos pueden ser resueltos si consideramos que reservar un lugar en la memoria
donde los argumentos podran colocarse en lugar de incluirlos en los registros.

La idea final es, por lo tanto, organizar los argumentos directamente en una pila:
no ms problemas de tamao (siempre que tengamos nuestra pila de tamao correcto,
es decir, hemos reservado suficiente espacio en la memoria para su funcionamiento)
ni problemas con guardar porque la pila crece, naturalmente, estamos avanzando
argumentos.

Los argumentos de un procedimiento as gestionado a travs de una pila (es decir,


colocado en la pila antes de la llamada, utilizada en el procedimiento, y luego se
eliminan al regreso a la funcin de llamada) pertenecen a la categora de datos
dinmicos. Esto significa que se crean y se destruyen en la demanda durante la
ejecucin. En general, estos datos se realizan en una zona de memoria libre, que se
llama el montn o pila de usuario. Aqu, podemos organizar parte de este montn en
la forma de una estructura LIFO gestionado por un registro general, Rn.

Por lo tanto tres pasos principales marcan la evolucin de este montn cuando se
trata de pasar argumentos:
- creacin: el programa llamante apila los argumentos antes de llamar al
procedimiento;
- Utilizacin: el acceso a los argumentos que se lleva a cabo con la ayuda del modo
de direccionamiento indexado indirecto [rn + #desplazamiento];
- Desaparicin: esto significa quitar los argumentos cuando ya no son de utilidad.
Hay dos opciones: o bien el llamado procedimiento quita de ellos, o el procedimiento
llamado unstacks ellos. Las siguientes secciones muestran las dos opciones.

REMARK 7.4.- as como la tcnica utilizada para realizar el paso de argumentos deben
ser parte de la documentacin proporcionada al utilizar un procedimiento, por lo que
el creador de un procedimiento utilizando la pila tambin deben informar a los futuros
usuarios de quin debe borrar la pila de argumentos de dumping antes de la llamada. A
priori, esta eleccin no tiene ninguna consecuencia concreta, sino que debe ser
absolutamente respetado. De hecho, una pila deriva no puede ser visto en una prueba
unitaria , pero en el caso de mltiples llamadas esta deriva podra provocar un
desbordamiento de pila, que pueden ser catastrficas.
128 Assembly Language Programming Internal Modularity 128

En los ejemplos siguientes, el montn se corresponde con un pre-decrementacin


pila, pero podramos haber elegido un post-incremento pila: no hace ninguna
diferencia. Tomamos R11 para ser el registro del puntero de pila en el argumento, y
suponemos que no ha sido adecuadamente inicializado para apuntar a la pila vaca
inicialmente. Ejemplo 7.5 muestra cmo esa reserva puede ser hecha. En este ejemplo,
el SP est inicializado dos veces para mostrar las dos diferentes, pero equivalentes,
sintaxis. Una inicializacin nica es suficiente.

EJEMPLO 7.5.- La reserva y la inicializacin de una pila de usuario

Tamao_Stack EQU 128


;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - zona MyData,
datos, ALIGN=2
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - User_Stack
ESPACIO 4*size_Stack ; reserva de espacio de memoria
superior_Stack ; para la pila
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - zona MyCode,
cdigo readonly, ALIGN=2
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
...
LDR, R11 = Top_Pile ; inicializacin directa
LDR, R11 = User_STACK_Stack Size + 4 *
; la sintaxis equivalente
...

7.2.4.1. Pasar argumentos por valor: el llamador unstacks


En esta cuarta versin, todos los argumentos se pasan por valor, incluso devolver
argumentos. Para ello, se hace un orificio en la pila, lo que significa que el valor 0 se
almacena antes de la llamada sin este valor es una utilidad en la entrada
del procedimiento. El nico objetivo de este almacenamiento es reservar el espacio
necesario para pasar el resultado devuelto, esta zona est modificado al final del
procedimiento.

Por convencin, en esta versin, el interlocutor est a cargo de la remocin de la


pila. Esto corresponde a un incremento de 12 bytes (tres argumentos de 4 bytes cada
uno) del SP justo antes del regreso a la persona que llama.

Debemos sealar que no hay, estrictamente hablando, la supresin de la


memoria pero simple liberar memoria en la elevacin de la aguja. As, durante el
siguiente uso los valores siguen presentes en la memoria, los casos slo en ese
momento sern destruidos por la sobreescritura.
129 Assembly Language Programming Internal Modularity 129

EJEMPLO 7.6.- investigacin en el mximo: pasando por usuario y por valor de pila

...
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Principales PROC

LDR, R0=ValOne

LDR R1,[R0]

STR [R1, R11,#-4] ! ; el apilamiento de argumento 1.

LDR, R0=ValTwo

LDR R2,[R0]

STR [R2, R11,#-4] ! ; el apilamiento de argumento 1.

MOV R1,#0

STR [R1, R11,#-4] ! ; el agujero para el argumento return

BL MaxVer4 ; llamada

LDR, R4= Maxi ; carga de direccin Maxi

LDR R1,[R11] ; carga del resultado

STR R1,[R4] ; el almacenamiento del resultado

Agregar R11,#12 ; limpieza de la pila

Infinito infinito B ; Fin del programa

ENDP

MaxVer4 PROC

Empujar {R1-R2} ; Guardar registros modificados

LDR[R1, R11, #8] ; la carga del primer argumento

LDR R2,[R11, #4] ; carga del segundo argumento

CMP R1,R2

BHS Bueno ; si ValOne < ValTwo ...

Intercambio MOV R1,R2 ; ... ValTwo pasa a ser el


mx.
130 Assembly Language Programming Internal Modularity 130

Bueno STR [R1, R11] ; el almacenamiento del


resultado

POP {R1-R2} ; Restaurar registros


guardados

BX LR ; Volver

ENDP

En este listado, los nmeros en crculos que aparecen no tienen nada que ver con
la sintaxis del ensamblador. Estos son slo los marcadores para ser comparados con
los que se muestran en la Figura 7.1. Que indican cmo el usuario sp evoluciona
durante la ejecucin del programa. Podemos compararlos con los breakpoints que
congelar el estado del procesador en un momento dado para observar las evoluciones.

Xx 00 00 00
xx 00 00 00
rea reservada para la pila

xx 01 01 01
xx 59 59 +8 59
xx 00 00 00
xx 00 00 00
xx 0A 0A 0A
xx BF BF +4 BF
xx 00 00 00
xx 00 00 00
xx 00 0A 0A
xx 00 BF BF
xx xx xx xx
xx xx xx xx
XXXX XXXX

Inicializ Apilamient El uso Limpieza


acin de o de de
pila argumento argumento
s s

Figura 7.1. Los argumentos pasados por valores en una pila de usuario

Tenga en cuenta que la pila est sujeta a pre-decremento, por lo que suponemos
que crece hacia la parte inferior de la memoria, es decir que la direccin actual de la
pila disminuye en el transcurso de apilamiento. En cada momento el
puntero R11 seala a la direccin donde el ltimo escrito fue llevado a cabo.

En este programa, el par de instrucciones mov#0, R1 y R1, LDR[R11#-4]! Puede


ser sustituido por una simple SUB R11 #-4. Hay buena equivalencia en la funcin
global, excepto que el valor del resultado es inicialmente indeterminada (no es
inicializada por valor 0), que en nuestro caso no tiene absolutamente ninguna
consecuencia. Un final, menos ortodoxa
131 Assembly Language Programming Internal Modularity 131

(pero ms ptimo en trminos de tiempo de procesamiento) opcin sera la pila slo


dos argumentos en la llamada. El programa llamado tendra entonces para apilar el
tercero, una vez que los clculos se efectan, en sobrescribir uno de los dos argumentos
de entrada.

7.2.4.2. Pasar argumentos por referencia: el llamado


unstacks
Aqu hay otra versin donde los tres argumentos son esta vez se pasa por referencia,
siempre por la pila. En esta versin es la responsabilidad de los llamados a desapilar.
Esta versin es un poco ms difcil de leer, porque utiliza el doble indirections, post-
y pre-offsets y mltiples lecturas. Veamos todo esto en detalle.

El programa de llamadas almacena las tres direcciones correspondientes a los tres


argumentos del procedimiento en la pila del usuario. En comparacin con el ejemplo
anterior, los pequeos cambios: siempre hay pre-decrementations de puntero R11. Lo
que sucede en el procedimiento es un poco ms compleja. El procedimiento primero
guarda los cinco registros (R1 a R5) utilizado por la secuencia. Hay entonces una
lectura mltiple (LDM!,R11 R3-R5), lo que significa que:

R3 [R11] por lo tanto, la direccin de Maxi


R4 [R11+4] por lo tanto, la direccin de ValTwo
R5 [R11+8] por lo tanto, la direccin de ValOne
R11 R11+ 12 despus del desplazamiento del puntero

Este es un cuatro en uno: hay operaciones en una sola lnea de instrucciones. No se


deje engaar, aunque la ejecucin requiere cuatro ciclos de reloj porque requiere cuatro
escritos a la memoria. Esta es la razn por la cual el Programa Registro de Estado x ()
utiliza IC Interruptible-Continuable xPSR)/ (SI) bits de entonces (vase la figura 2.4)
para realizar un seguimiento de la cantidad de escritos que se han completado. En el
caso de interrupcin, el Cortex-M3 puede completar el ciclo de escritura a su regreso.

REMARK 7.5.- Ya hemos observado el doble rareza del conjunto de instrucciones


(vase la seccin 5.7.2). R11 acta como un puntero, pero no necesita soportes y un
signo de exclamacin que significa, en este caso, un post-desplazamiento (y no una
pre-desplazamiento, como para un clsico LDR). Este viaje usted puede!

La lectura de ValTwo ValOne y valores y la escritura del resultado en Maxi se


consigue mediante sealizacin doble. Como se muestra en la Figura 7.2, el R11 es el
primer puntero que permite la inicializacin de punteros auxiliar R4 y R5 para asignar,
con un segundo puntero, R1 y R2 en la entrada. Tambin permite la inicializacin de
puntero auxiliar R3 para escribir el resultado contenida en R1. Nos gustara poder
utilizar este doble apuntando en una sintaxis general:
132 Assembly Language Programming Internal Modularity 132

LDR R1,[[R11]] ; el horror!!!!

Pero esta sintaxis no existe. Esto es comprensible porque significa dos diferentes
pero activaciones simultneas del bus de acceso a la memoria.

EJEMPLO 7.7.-

...
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Principales PROC
LDR, R0=ValOne

STR [R0, R11,#-4]! ; el apilamiento de @


argumento 1.
LDR, R0=ValTwo
STR [R0, R11,#-4]! ; el apilamiento de @
argumento 2
LDR, R0= Maxi
STR [R0, R11,#-4]! Apilamiento ; @ del
argumento return
BL MaxVer5 ; llamada
Infinito infinito B ; Fin del programa
ENDP
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MaxVer5
PROC ; Guardar los registros modificados
Empujar {R1-R5} ; Guardar los registros modificados
LMD R11 !{R3-R5} ; Mltiples lectura del 3 @
arg.
; y post incremento
; =>limpieza al mismo tiempo
LDR R1,[R5] ; la carga del primer argumento LDR R2,[R4] ;
carga del segundo argumento CMP R1,R2
BHS Bueno ; si ValOne < ValTwo ... Intercambio
MOV R1,R2 ; ... ValTwo pasa a ser el
mx.
Buena STR R1,[R3] ; el
almacenamiento del resultado POP
{R1-R5} ; Restaurar registros
guardados BX LR ; Volver
ENDP
133 Assembly Language Programming Internal Modularity 133

@ValOne31-24
@ValOne23-16
@ValOne15-8 00
3
@ValOne7-0 @ValOne31-24 00
Zona reservada para la

@ValTwo31-24 @ValOne23-16 00

R5
@ValOne
@ValTwo23-16 @ValOne15-8 00 Maxi
@ValTwo15-8 @ValOne7-0 3
00

R4
@ValTwo7-0 @ValTwo31-24 @ValTwo Yyyyyyyy
00

R2
@MaXi31-24 @ValTwo23-16 0A
@Maxi23-16 @ValTwo15-8 R BF ValTwo
@Maxi15-8 @ValTwo7-0
00
pila

R3
@Maxi Xxxxxxxx
@Maxi7-0 @MaXi31-24
00
Xx

R1
@Maxi23-16
01
xx @Maxi15-8 ValOne
59
@Maxi7-0 xx
xx XX
xx
XX
XXXX

El Uso y limpieza de Sealiza


llenado la pila cin
de la pila doble

Figura 7.2. Los argumentos pasados por referencia sobre una pila de usuario

7.2.5. Pasar argumentos por la pila del sistema

Esta es la ltima variante que presentaremos (Ejemplo 7.8 y Figura 7.3) para
ilustrar el paso de argumentos. En lugar de pasar argumentos por una pila
administrada por un registro general, podemos pasar argumentos por el apilado en la
pila del sistema. Esto es gestionada por el sistema SP. Este es utilizado regularmente
por los compiladores y implica que la pila del sistema debe ser de tamao suficiente.

Debemos reconocer que, adems del problema del mximo tamao de la pila, el
uso de la pila del sistema es bastante delicado, aun en el caso del ensamblador del
brazo no es el ms crtico de1. Las dificultades provienen del hecho de que la pila del
sistema se usa para otras cosas que no sean el simple paso de argumentos. Este es
especialmente el caso cuando se guardan datos temporales (contenido del registro, la
direccin de retorno en el caso de llamadas anidadas, etc.); en consecuencia, la SP
flucta segn el push/POP insertado en el procedimiento. Por lo tanto, debemos
considerar estas fluctuaciones para alcanzar los argumentos.

1 La mayora de los ensambladores almacenar la direccin de retorno en la pila del sistema, en


lugar de en un registro especfico, cuando se realice una llamada a un procedimiento. Existe,
pues, una mezcla de argumentos, direcciones de retorno y otros guardar registros, lo cual
complica la gestin de esta pila.
134 Assembly Language Programming Internal Modularity 134

Una opcin ms segura es utilizar un puntero anexo: es congelado a la entrada del


procedimiento (despus de que l mismo es guardado) en el valor actual del SP. Por
lo tanto, es independiente de las fluctuaciones mencionadas anteriormente y facilita
la gestin de recuperacin de argumento. En el siguiente ejemplo, el R9 Registro
desempea esta funcin del anexo puntero. La sp evoluciona (rodeado con un crculo
los nmeros), junto con los diferentes stackings/unstackings. Cabe sealar , y este
punto es sumamente importante, que en la devolucin de llamada del SP es devuelto
a su punto inicial. El procedimiento de llamada ha realizado la compensacin (el
llamado programa podra muy bien haber hecho lo mismo). Una lectura mltiple
eleccin (LDM (carga mltiple)) tambin ha sido hecha para la recuperacin de los
argumentos en la pila del sistema. Como esta instruccin no nos permiten tener una
compensacin complementaria en sus modos de direccionamiento, era necesaria para
compensar el R9 por cuatro bytes en la parte superior de la pila, por lo que el programa
puntero est correctamente posicionado en los argumentos para ser recuperados. Una
alternativa a esta versin es para llevar a cabo lecturas individuales (LDR (Registro
de carga) con compensacin suplementaria.

Por ltimo, tenga en cuenta que no es posible recuperar argumentos con


la instruccin pop o, ms precisamente, si aplicamos esto ya no es posible garantizar
la no modificacin de los registros afectados por el procedimiento.

EJEMPLO 7.8.- investigacin en el mximo: pasar por referencia y por pila del
sistema

...
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Principales PROC
LDR, R0=ValOne
Pulsar R0 ; el apilado de @
Parmetro 1
LDR, R0=ValTwo
Pulsar R0 ; apilar @ Parmetro 2
LDR, R0= Maxi
Pulsar R0 ; el apilamiento del
parmetro de
BL MaxVer6 ; llamada
devolucin
Infinito B infinito ; Fin del programa
ENDP
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MaxVer6 PROC
Empujar {R9} ; Guardar registro
modificado
MOV R9,SP ; la inicializacin del anexo
puntero
Agregar R9#4 ; Offset en R9
Empujar {R1-R5} ; Guardar registros
modificados
135 Assembly Language Programming Internal Modularity 135

La LDM {R9, R3-R5} ; carga del 3 @ argumentos LDR R1,[R5] ;


la carga del primer argumento LDR R2,[R4] ; carga del segundo
argumento CMP R1,R2
BHS Bueno ; si ValOne < ValTwo ... Intercambio MOV R1,R2 ; ...
ValTwo se convierte en el buen max STR R1,[R3] ; el almacenamiento del resultado
POP {R1-R5,R9} ; Restaurar registros guardados
SUB SP.#12; limpieza de la pila del sistema
BX LR ; Volver
ENDP

Figura 7.3. Pila del sistema evolution (mostrando el cdigo de ejemplo 7.8)
136 Assembly Language Programming Internal Modularity 136

7.2.6. En el arte de mezclar

Todas las versiones de pasar argumentos que han sido presentados en las secciones
anteriores se pueden mezclar a voluntad. Esta es la fuerza y la flexibilidad de la
programacin en lenguaje ensamblador, pero es tambin la dificultad. En efecto,
podemos, por ejemplo, pasar un primer argumento por valor y por registro, un segundo
por referencia y por el sistema de pila y recuperar los resultados del procedimiento en
una pila de usuario. Es fcil comprender que esa mezcla corre el riesgo de ocasionar
terribles problemas. Por lo tanto, salvo que se estn obligadas (por motivaciones que
puede aparecer oscura) para hacerlo, lo mejor es evitar la mezcla.

7.3. Los datos


locales

Para llevar a cabo su labor, una subrutina puede tener que utilizar sus
propios datos. Estos son los datos locales de la subrutina. La regla de localizacin nos
invita a poner estos datos de modo que slo son visibles y utilizables por la subrutina
patentados. La manera ms sencilla de hacerlo en lenguaje ensamblador es utilizar
los registros generales para contener las variables locales. Funciona perfectamente en
los casos ms simples, especialmente si los datos no son demasiado numerosos.
Lamentablemente, el nmero de registros est limitado. Lo que es ms, este mtodo
no es til en el caso de llamadas a subrutinas anidadas o para una funcin recursiva
sin necesitar varios salva. Podramos considerar la planificacin de la creacin de
estos datos en una seccin de datos especficos, pero esto lleva a un "desecho" de la
memoria porque slo se utiliza durante la ejecucin del procedimiento. Una solucin
ms satisfactoria sera superponer todas estas secciones especificndolas como
siendo comunes, que se especifican como atributos en la declaracin de la
seccin: REA DE DATOS Mydata align=2, comn, por lo que comparten la misma
porcin de memoria. No obstante, podemos aplicar las mismas crticas a este mtodo
de superposicin en el caso de argumentos dispuestos en un espacio fijo: el
lanzamiento de una subrutina puede conducir a una prdida parcial o total de datos
locales desde el programa que realiza la llamada. Por tanto, preferimos crear los datos
en una forma dinmica al comienzo de la ejecucin del procedimiento. Aqu hay dos
opciones, ambas con el montn:
- adems de la pila de los argumentos, podemos utilizar una segunda pila para las
variables locales.
- durante la ejecucin podemos colocarlos en la misma pila como los argumentos.

REMARK 7.6.- variables locales creado dinmicamente en una pila puede igualmente
ser creado en una pila de usuario (un montn) o en la pila del sistema. Como en el caso
de pasar argumentos, el uso de la pila del sistema es ms delicado y, por tanto,
peligrosa. Como tal, si no hay imperativos vinculados al uso de la memoria, siempre
es preferible y ms seguro utilizar la pila del usuario.
137 Assembly Language Programming Internal Modularity 137

Vamos a ilustrar el uso de una pila de usuario, tras lo cual tanto el procedimiento
argumentos y variables locales se pueden arreglar. Suponemos que la pila de usuario
se crea e inicializa debidamente, con R11, como el registro SP.

7.3.1. Reserva simple de datos locales

En primer lugar, veamos un primer mtodo donde las variables locales son
simplemente reservado en la pila del usuario por el programa que realiza la llamada.
El procedimiento considerado en el ejemplo 7.9 y Figura 7.6 empieza por restablecer
las variables locales, el cuerpo del procedimiento al no haberse desarrollado.
Suponemos que el procedimiento recibe dos argumentos de 32 bits,
denotados Arg1 , Arg2, que estn almacenados en la misma pila de usuario durante la
llamada.

REMARK 7.7.- No es necesario considerar que las variables locales son inicializadas a
cero. De hecho, ocupan un espacio de memoria que se pueden utilizar muchas veces,
y la liberacin de memoria se realiza slo por compensacin punteros dirigidos a la
memoria de las zonas de que se trate. Los valores son, por tanto, ni borrarse ni
guardado.

Las diferentes etapas de la gestin de la pila del usuario para la gestin de las
variables locales son:
- Creacin: tomemos el caso de cuatro variables locales: uno de 32 bits, uno de los
16 bits, y dos de 8 bits. En la parte superior de los argumentos, nos reservamos un lugar
(4+2+1+1 bytes) creando un agujero en la pila, gracias a esta instruccin colocado al
inicio del procedimiento: SUB R11#8.
- Uso: Distribuimos estos 8 bytes a voluntad entre las distintas variables locales.
En el ejemplo 7.9, el datum Local32 (32 bits) se alcanza
por [R11,#4], el datum Local16 (16 bits) por [R11,#2], 1 Byte (8 bits)
por [R11,#1] y 2 Byte (8 bits) por [R11]. Tenga en cuenta que estos smbolos no estn
definidos a priori.
- Extraccin: esto es llevado a cabo por un desplazamiento hacia la parte superior
de la pila que se utiliza para rellenar el hueco. Podemos utilizar este paso, como se ha
hecho en este ejemplo, tambin se quitan los dos argumentos que se pasan en la
llamada, que en nuestro caso corresponde a la instruccin ADD R11,#16.
EJEMPLO 7.9.- Borrar de variables locales.

Borrar_Local PROC
Empujar {R1,R2,R10} ; Guardar registros
modificados
MOV R10,R11 ; anexo asignacin de
puntero
SUB R11,#8 ; "hueco" para las 4
variables locales
MOV R2#0 ; para borrar
STR [R2, R11,#4] ; Borrar32 Local.
138 Assembly Language Programming Internal Modularity 138

STRH[R2, R11,#2] ; Borrar16 Local.


STRB[R2, R11,#1] ; Borrar Byte2
STRB R2,[R11] ; Borrar Byte1
LDR[R1, R10,#4] ; carga de 1 parmetros
LDR R2,[R10] ; carga del segundo parmetro
...... Cuerpo de ;
...... ; el procedimiento
Agregar R11,#16 ; extraccin de local
; (8) variables y
argumentos (8) Pop {R1,R2,R10} ;
Restaurar registros guardados
BX LR ; Volver
ENDP

Un anexo puntero (R10) fue despus de la inicializacin (guardar) para acceder a


los argumentos. Esta opcin no es obligatoria; simplemente nos permite tener punteros
distintos para acceder a los argumentos y las variables locales, que pueden ser ms
tiles y, sobre todo, mucho ms legible. Sin embargo, la llamada argumentos siguen
siendo accesibles desde R11+8. La figura 7.6 corresponde a la configuracin de la
pila del usuario, una vez haya hecho la reserva para las variables locales y anexo
puntero R10 ha sido inicializado (despus del SUB R11#8 de las instrucciones).

Tomemos el ejemplo del clculo (por el Max_cuatro procedimiento) de un


mximo de una tabla de cuatro enteros sin signo. Estos nmeros se
denomina N1, N2, N3 y N4 en el procedimiento. Max_cuatro recibirn estos cuatro
argumentos que se pasan por valor de la pila del usuario. Lleva a cabo su clculo
llamando a la funcin MaxVer4 tres veces, tal y como se define en el Ejemplo 7.6.
Todos sus argumentos tambin se apilan por valor. El procedimiento devuelve el
resultado por valor mediante el registro R4.

Aqu estn las expresiones de este clculo:

M1 = mximo (N1, N2,


M2) = mximo (N3,N4)
Resultado = mximo (M1,M2)

Ponemos M1 y M2 en variables locales y aplicar la regla de "quien pilas,


unstacks!".
139 Assembly Language Programming Internal Modularity 139

La figura 7.4. Lugar relativo de las variables locales en la pila (ver ejemplo 7.9)

Comencemos con las pocas lneas de llamada que simplemente utilizar post-
incremento para la lectura de los diferentes valores de tabla (apuntado por R0) y pre-
decrementacin por escrito a la pila (sealado con R11).
140 Assembly Language Programming Internal Modularity 140

EJEMPLO 7.10.- Llamada al procedimiento Max_4

...
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Principales PROC
...
LDR R11=Top_stack
LDR, R0=Tabla
LDR R1,[R0],#4
STR [R1, R11,#-4]! ; Tabla Pila[0] (N1) LDR R1,[R0],#4
STR [R1, R11,#-4]! ; Tabla Pila[1] (N2) LDR R1,[R0],#4
STR [R1, R11,#-4]! ; Tableau Pila[2] (N3) LDR R1,[R0]
STR [R1, R11,#-4]! ; Tabla Pila[3] (N4).
BL Max_4
Agregar R11,#16 ; quien apila unstacks
LDR, R0=ResuMax
STR R4,[R0] ; el resultado es en R4
Infinito B infinito ; Fin del programa
ENDP

Ahora veamos el procedimiento en s. Este anuncio est acompaado por nmeros


en crculos que, con la ayuda de la Figura 7.5, nos permiten visualizar el estado de la
pila de usuario justo despus de la ejecucin de las instrucciones marcadas.

EJEMPLO 7.11.- Cuerpo del procedimiento Max_4

Max_4 PROC
Empujar {LR} ; llamadas anidadas
Empujar {R1,R2,R10} ; Guardar registro
modificado
MOV R10,R11 ; la inicializacin del
SUB R11,#8 argumento puntero
; el agujero para crear
LDR[R1, R10,#12] ;
2 Carga N1 locales
variables
STR [R1, R11,#-4]!
LDR[R1, R10,#8] ; Carga N2
141 Assembly Language Programming Internal Modularity 141

STR [R1, R11,#-4]!


MOV R1,#0
STR [R1, R11,#-4]! ; Agujero en la pila para volver
BL MaxV4
LDR R1,[R11]
STR [R1, ; Asignacin de M1
R11,#16] Aadir R1 ; Quien apila unstacks
1,#12 R10,#4]
LDR[R1, ; Carga N3
STR [R1, R11,#-4]!
LDR R1,[R10] ; Carga N4
STR [R1, R11,#-4]!
MOV R1,#0
STR [R1, R11,#-4]! ; Agujero en la pila para volver
BL MaxV4
LDR R1,[R11]
STR [R1, ; Asignacin de M2
R11,#12] Aadir R1 ; Quien apila unstacks
1,#12
LDR[R1, R11,#4] ; Asignacin de M1
STR [R1, R11,#-4]!
LDR[R1, R11,#4] ; Asignacin de M2
STR [R1, R11,#-4]!
MOV R1,#0
STR [R1, R11,#- ; Agujero en la pila para volver
4]! BL MaxV4
LDR R4,[R11] ; Asignacin del resultado final
; (retour a travs de R4).
Agregar R11,#12 ; Quien apila unstacks

Agregar R11,#8 ; Espacio libre enrelacina variables locales


POP {R1,R2,R10} ; Restaurar registros modificados
POP {LR} ; Restaurar relativos a llamadas anidadas
BX LR ; Volver

ENDP
142 Assembly Language Programming Internal Modularity 142

Reconocemos que no son simples, ms rpidas y precisas formas de calcular un


promedio de cuatro nmeros. Este ejemplo pretende dar una imagen condensada de
varios puntos tratados anteriormente (paso de argumentos complejos, pila, el modo de
direccionamiento, variables locales, etc.).

argumentos
Max_cuatro
N1 N1 N1
argumentos
Max_cuatro

argumentos
Max_cuatro
N2
N2 N2
N3
N3 N3
R10 R10 R10 N4
N4 N4
M1=max(N1,N2)
Local

Local
M1=? M1=?
Los argumentos locales

M2=? R11
es

es
R11
M2=? M2=?
N1
Xxxxxxxx N1
N2
Xxxxxxxx N2
MaxV4

R11 Max(N1,N2)
Xxxxxxxx 0
Xxxxxxxx
Xxxxxxxx Xxxxxxxx

N1 N1 N1
argumentos
Max_cuatro

argumentos
Max_cuatro

argumentos
Max_cuatro

N2 N2 N2

N3 N3 N3
Local

R10 R10 R10


locales

locales

N4 N4 N4
es

M1=max(N1,N2) M1=max(N1,N2) M1=max(N1,N2)


R11
Los argumentos

Los argumentos

M2=? M2=max(N3,N4) M2=max(N3,N4)

N3 N3 M1
MaxV4

MaxV4

N4 N4 M2
R11 R11
0 Max(N3,N4) Max(M1,M2)

Xxxxxxxx Xxxxxxxx Xxxxxxxx

Figura 7.5. Max_4: Evolucin de la pila de usuario


143 Assembly Language Programming Internal Modularity 143

7.3.2. Utilizando una lista encadenada

7.3.2.1. Punto Fijo en la pila


Ejemplo 7.11 mostr cmo delicadamente el mtodo propuesto anteriormente debe
ser utilizado. Est claro que la posicin actual de R11 debe estar perfectamente
dominado: cualquier error en la alineacin de pila es fatal para la ejecucin del programa.
Como cada vez que se agregan elementos a esta pila y, a continuacin, eliminarlos, la
posicin relativa de los argumentos y las variables locales se modifica, nos damos cuenta
de que la re-lectura de un programa ser difcil, laborioso, las modificaciones y los
errores formidables.

El mejor mtodo consiste en sacrificar un registro - digamos - R9 de manera que


marca un punto fijo, una especie de anclaje en la pila. Esta es la tcnica que se utiliza
para separar el acceso a los argumentos de acceso a las variables locales. As
congelados, todos los desplazamientos se calcular a partir de este punto fijo, de tal
forma que SP R11 contina viviendo su vida independiente yo-yoing a lo largo de la
pila. La posicin de elementos apilados tambin es separado del R11. Una vez ms,
todo el trabajo se devuelve al procedimiento llamado de manera similar a lo que se ha
hecho con la gestin de registro R10 para acceso del parmetro.

Aplicando al ejemplo del restablecimiento de las variables locales, las lneas

de cdigo son: Ejemplos de 7.12.- Reinicio de variables locales: versin con anexo

puntero

Borrar2_Local PROC
Empujar {R1, R2, R9, R10} ; Guardar los registros modificados
MOV R10,R11 ; Anexo puntero (argumentos)
MOV R9,R11 ; Anexo puntero (variables locales)
SUB R11,#8 ; Agujero para crear las 4 variables
MOV R2#0 ; locales
Para borrar
STR [R2, R9,#-4] ; Reset 32 Local.
STRH[R2, R9,#-6] ; Reset 16 Local.
STRB[R2, R9,#-7] ; Restablecer Byte2
STRB[R2, R9,#-8] ; Resto Byte1
LDR[R1, R10,#4] ; La carga del primer parmetro
LDR R2,[R10] ; Carga de parmetros 2
...... ; Cuerpo de
...... ; El procedimiento
Agregar R11,#16 ; Extraccin de local
; (8) variables y argumentos (8)
POP {R1,R2,R9,R10} ; Restaurar registros modificados
BX LR ; Volver
ENDP
144 Assembly Language Programming Internal Modularity 144

Figura 7.6. Lugar relativo de la variable local localizaciones en la pila (ver ejemplo 7.12)

7.3.2.2. Encadenamiento
Hemos generalizado el mtodo anterior para todos los llamados procedimientos,
sino que se utiliza el mismo registro R9 como la pila anexo puntero. Por tanto,
tomemos el caso de un procedimiento proc1 llamar a un procedimiento proc2, que
llama a un procedimiento proc3.
145 Assembly Language Programming Internal Modularity 145

Pongmonos en el ms profundo nivel de llamadas (vase la figura 7.7) y, por tanto,


al comienzo de proc3. R9 puntos a su guarda, que indica la posicin de R9 en el inicio
de la llamada a proc2, que indica la posicin de R9 en el inicio de la
llamada a proc1. R9 gestiona por tanto una lista encadenada, que nos permite, sin
alterar el valor contenido en R9, para recuperar cualquier variable local o un argumento
de proc1 y proc2 empezando por proc3.

Figura 7.7. Variables locales: estado de la pila de usuario

Es suficiente con esto para poder recuperar los valores anteriores de R9, sin cargar
su valor actual; por ejemplo, vea los siguientes temas:
146 Assembly Language Programming Internal Modularity 146

EJEMPLO 7.13.- Llamada anidada encadenados y variables locales

LDR R4,[R9] ; R4 R9 para backup proc2


LDR R5,[R4] ; R5 R9 para backup proc1

La figura 7.7 muestra cmo los diferentes argumentos anidan en la pila del usuario.
Si lo deseamos, esto nos permite implementar una jerarqua de las variables locales,
como permitido en Ada, por ejemplo. De hecho, esta jerarqua es muy interesante
para escribir un compilador, pero poco utilizado porque es muy pesado para el trabajo
actual de un programador en general
Idioma en un controlador .
Captulo 8

Gestin de
excepciones

La comprensin de los mecanismos de excepcin es un paso esencial a la hora de


hardware del equipo. El ncleo de un controlador es responsable de la ejecucin de
algoritmos, gestin de tareas y clculos necesarios para el proyecto, pero todos de esta
organizacin sera intil si no iba acompaada de la posibilidad de
La interconexin electrnica (en el sentido) con el proceso fsico que tiene que
administrar. Como se explic en el Captulo 1, es la responsabilidad del controlador
designer (y no la mquina RISC avanzada o brazo) para desarrollar estos perifricos.
Estos pueden ser considerados como micromachines que son independientes del
ncleo y realizar
Tareas especficas (contando el tiempo, convertir una seal analgica en su
equivalente numrico, peridicamente, generando una seal cuadrada, etc.). Su medio
preferido de comunicacin es la interrupcin. Mediante este mecanismo, los
micromachine seales a Cortex-M3, asincrnica con el actual cdigo de ejecucin, que
ha terminado su tarea y que Cortex-M3debera responder en consecuencia.

Un mecanismo similar se acopla cuando, durante la ejecucin de una secuencia de


cdigo, un evento "en serio" y su tratamiento requiere un rgimen particular. Como
ejemplo, tomemos el caso de un intento de leer el contenido de una direccin de
memoria que, por alguna razn, falla. Este tipo de evento es estrictamente especficos
para el funcionamiento del ncleo y generalmente es lanzado de forma sincrnica con
una instruccin. Es posible entonces hablar de trampas de software.

Por ltimo, otro tipo de comunicacin puede surgir, que se refiere a la puesta en
marcha de un reinicio o una interrupcin no enmascarable (NMI). Estos dos
acontecimientos son generalmente transmitidos por pasadores externos especficos del
procesador y puede considerarse como una "parada de emergencia".
148 Assembly Language Programming Managing Exceptions 148

Interrumpe, trampas, Reset y NMI vienen bajo el trmino genrico de excepciones.


La tcnica utilizada para responder a estos distintos casos de "excepcin" es similar y
es el tema de este captulo. El controlador de interrupciones de vectores
anidados (NVIC) recibe rdenes y gestiona todas las excepciones, por lo que en este
captulo, veremos en detalle muchos de los registros de esta unidad.

8.1. Qu sucede durante


el restablecimiento?

Antes de describir estos mecanismos y qu consecuencias implican a un nivel de


programacin en mayor detalle, veamos el caso de Restablecer. Este es el ms serio y
ms ineludible de excepcin del evento (o, para ser ms precisos) que puede
Suceder a cualquier procesador . Un restablecimiento del sistema pueden tener
diferentes orgenes. En el caso de
Cortex-M3, estos pueden
ser:
- exterior, lo que significa que un circuito particular pin que deber, de forma
predeterminada, en una lgica de alto nivel ha pasado a un nivel bajo;
- lanzada por un vigilante1;
- lanzado por el software estableciendo el bit SYSRESETREQ de la aplicacin
Interrumpir y restablecer el registro de control (en el NVIC
AIRCR) a 1.

Reset tambin corresponde a un "arranque en fro", o el encendido del circuito. Si


se corresponde con el ajuste del pin de reset del circuito a un nivel inferior (conocido
como un restablecimiento en la prctica correspondiente al usuario pulsar un botn
conectado a este pin), generalmente no es un buen augurio para el progreso de la
aplicacin que se est ejecutando en el procesador.

Durante una fase de restablecimiento, el procesador inicia reinicializando todos


los registros. En la documentacin, encontramos el valor tomado por cada registro
tras un reset. Esta inicializacin coloca el procesador en modo de subproceso
privilegiado. Luego Cortex-M3 lee el contenido de la direccin 0x00000000 (la
direccin de asignacin de memoria ms bajo) para asignarle el registro R13. Una vez
hecho esto, se inicializa el puntero de pila. Esta primera asignacin es imprescindible,
pues una excepcin puede ocurrir en cualquier momento y porque el tratamiento de
esta excepcin, como veremos ms adelante, requiere acceso a la pila del sistema. El
procesador debe por lo tanto estar en una posicin para procesar una excepcin y, por
consiguiente, debe disponer de una cuenta vlida de puntero de pila. La direccin de
memoria registrada en estas
4 bytes debe corresponder a la parte superior de una zona de memoria con acceso de
lectura/escritura. En una tercera etapa, Cortex-M3 lee el contenido de la palabra
siguiente, es decir, el contenido de las direcciones 0x00000004 a 0x00000007. Esta
palabra se utiliza en la inicializacin de

1 Los guardianes son bits que debe (cuando estas unidades estn conectados) que
peridicamente se establece en 1. Este mecanismo permite a los controller para garantizar que
la ejecucin del programa no est bloqueado en un bucle infinito, entre otras cosas.
149 Assembly Language Programming Managing Exceptions 149

El puntero de instruccin (R15). Se debe, por tanto, corresponden a una direccin en


el cdigo de la zona donde la rutina de inicio que permite la inicializacin correcta de
todo el procesador, dependiendo de las caractersticas de la aplicacin, se almacena.

Este mecanismo trae a la luz el concepto de la tabla de vectores de


interrupcin (IVT) o Tabla de Descriptores de Interrupciones (IDT), vase la figura
8.2). En esta tabla, adems de que el valor inicial del puntero de pila, debe contener
las direcciones de todos los manipuladores de interrupcin (tambin conocida como
una rutina de servicio de interrupcin (ISR) para las posibles excepciones. El
ensamblador (o el compilador en el caso de idiomas de nivel superior), por lo tanto, se
encargan de la creacin de este modo que cuando se produce una excepcin, el proceso
actual est correctamente desviado a la asociada de ISR. Ejemplo 8.1 muestra cmo
comienza a crear esta tabla. Todos los valores iniciales (Reset_Handler,
NMI_Handler, etc.) corresponden a procedimientos que el vinculador ser capaz de
localizar para completar correctamente la tabla.

EJEMPLO 8.1.- Inicializacin de IVT

Reinicio de rea, DATOS


READONLY Vectores de exportacin
Vectores iniciales DCD_sp ; @ de la parte superior del espacio de memoria
; reservada para la pila
DCD Reset_Handler ; @ de subrutina Reset_Handler
DCD NMI_Handler ; @ de subrutina nmi_Handler
DCD HardFault_Handler ; @ subrutina DCD
MemManage
HardFault_Handler_Handler ; @
subrutina DCD BusFault
MemManage_Handler_Handler ; @
de subrutina BusFault_Handler
... ...

Cada excepcin tiene una entrada en la tabla que se encuentra en su posicin. As,
la direccin de memoria donde la direccin de la rutina de procesamiento para el
nmero de excepciones "posicin" se almacena corresponde a:

@Input_Treat = @Base Posicin + 4 *

Cuando @Base se fija en la zona de cdigo en 0x00000000. Debemos tener en cuenta


que con esta configuracin no es posible redefinir el IVT dinmicamente (es decir,
durante un programa) porque se crea y se establece durante la creacin del archivo
ejecutable. Gestin dinmica de la tabla puede ser til para permitir que el procesador
para reaccionar a la evolucin de su entorno. Esta opcin de reubicar la IVT es
posible. Para ello, es necesario proveer una zona de memoria 4*(N + 1) bytes, donde
N es el nmero mximo de excepciones que componen la tabla. Esta nueva zona de
memoria debera ser creado en memoria de datos si se desea una gestin dinmica, pero
es
150 Assembly Language Programming Managing Exceptions 150

Tambin es posible llevar a cabo una reasignacin esttica sencilla colocndola en


la zona de cdigo. En el registro del NVIC VECTTBL (consulte la Figura 8.1, es
posible especificar una direccin relativa (con respecto a la base de la SRAM [Static
random-access memory] o cdigo de acuerdo con la eleccin de la zona fijada por
el TBLBASE bits) para esta nueva tabla. Esta manipulacin requiere mucha
precaucin, especialmente en lo que se refiere a la alineacin de direcciones en esta
zona. Tambin debe garantizarse que el cambio no poner el procesador en una
situacin ambigua perfectamente inicializar esta nueva IVT antes de reasignar el
registro.

Figura 8.1. Registro de desplazamiento de la tabla de vectores de interrupcin (NVIC_VECTTBL)

EJEMPLO 8.2.- El ejemplo del controlador de


Reset

Reset_Handler PROC
Exportar Reset_Handler [principal]
Importacin dbiles
LDR R0, =principales
BX R0
ENDP

Cuando procesa un restablecimiento, el ejemplo tpico presentado en el ejemplo


8.2 es que podemos encontrar mediante el desarrollo del propio brazo suite, Kit de
Desarrollo de Microcontrolador Keil (MDK)-brazo. Durante el lanzamiento de Reset,
el procesador saltar a la direccin del procedimiento principal (con dos smbolos de
subrayado - Ser consciente de esto!), que ha sido creado en otras partes del proyecto
( de ah el uso de una importacin). Este procedimiento generalmente no existe en el
proyecto, pero se incluyen automticamente utilizando la librera MicroLib ( opcin
de montaje). Este procedimiento proporciona, entre otras cosas, el cdigo que
inicializa las variables en el proyecto (que corresponde al uso de directivas , DCW
DCB, etc.) y termina con un salto al procedimiento principal (sin guiones bajos) que,
por convencin, el
151 Assembly Language Programming Managing Exceptions 151

Punto de entrada de su proyecto. Es perfectamente posible hacerlo sin MicroLib,


mediante otro procedimiento (vase, por ejemplo, el uso de un compilador
GNU/ensamblador en el apndice D) o mediante el desarrollo de uno que est
especialmente dedicado a una configuracin especfica, pero el trabajo es
relativamente considerable y a menudo delicadas.

8.2. Las posibles


excepciones

Reset y NMI pueden considerarse como solicitudes de excepciones especiales.


Tambin son inevitables, en la medida en que su aparicin es imposible para inhibir y
su nivel de prioridad les da prioridad por encima de todas las dems fuentes posibles.
Los otros posibles excepciones pueden mostrarse en una IVT, vase la figura 8.2. De
hecho, para cada excepcin es necesario proveer a la rutina de procesamiento
correspondiente y, en consecuencia, para almacenar su direccin en el cuadro. Estas
rutinas antes mencionados no necesitan ser siempre porque podemos confiar en el
hecho de que las excepciones no se producir. Un tal hiptesis es completamente
controlable a nivel de interrupciones, pero presenta un reto especialmente arriesgado
cuando se trata de capturas

Ejemplo 8.3 de procesamiento NMI demuestra que es ms sencillo


para proporcionar el procesamiento de una excepcin (pero no el ms efectivo en el
caso de una aplicacin incrustada), ya que asciende a un bucle infinito
(B. Corresponde a un salto a su propia direccin). Se podra pensar que esto sera
suficiente en esta fase de desarrollo, pero ciertamente sera necesario proporcionar
algo ms robusto para una aplicacin autnoma. Cabe sealar que la exportacin
de NMI_Handler es del tipo dbil. Este es, por lo tanto, el mnimo indispensable
creados y proporcionados por el entorno de desarrollo. De esta manera, el desarrollador
podra disear una ms especfica y eficaz procesamiento de esta excepcin en otras
partes del proyecto que sera sustituida por esta primera versin, y la direccin de lo
que en definitiva sera llenar la IVT.

EJEMPLO 8.3.- El ejemplo de un manejador


de NMI

NMI_Handler PROC
Exportar nmi_Handler dbil [B] .
ENDP
152 Assembly Language Programming Managing Exceptions 152

Figura 8.2. Una tabla de vectores de interrupcin (TVI)


153 Assembly Language Programming Managing Exceptions 153

8.2.1. Trampas

Las entradas del 3 al 15 de la IVT conforman el conjunto de software de trampas.


La primera para corresponder a los fallos. Se trata de graves acontecimientos para que el
procesador no puede finalizar correctamente una instruccin. En la ocasin que estos
fallos aparecen, brazo ha proporcionado los medios para rastrear el origen de estos
fallos a travs de un registro "triple":
- MMFSR (Administrar memoria fallo Status Register);
- BSFR (Fallo de Bus Status Register);
- UFSR (Fallo de uso Status Register).

Esta es una triple registrarse en el sentido de que estos tres nombres corresponden
a 2 bytes y un semi-palabra de una palabra de memoria NVIC colocado en
0xE000ED28 (vase la figura 8.4). La lectura de la palabra MMFSR dar pues los tres
registros, pero la lectura de 1 byte en esta misma direccin slo da el contenido del
primer byte. La MMSFR es por lo tanto parte del registro. Un usuario encuentra un
problema de "fallo" podra, mediante la lectura del contenido de estos registros,
rastrear la causa de estos fallos. Slo el contenido de UFSR sern explicados (vase la
seccin 8.2.1.4) como en todo el mundo corresponden a cuestiones que abarcan
software en lugar de hardware, y para que un desarrollador pueda responder.

8.2.1.1. Fallo de disco: un fallo grave de hardware


Un incidente duro trampa tambin podra ser llamado un doble fallo. Esta captura
se activa en caso de un fallo de uso, avera del bus o la administracin de memoria
fallo surge pero su procesamiento no funciona (el TVI est mal inicializado, por
ejemplo). Tambin puede corresponder a un fallo del bus durante la lectura de la TVI.
Esta trampa es, pues, muy grave, porque corresponde al procesador es incapaz de
responder a un problema que requiere un tratamiento especfico. Como veremos ms
adelante, se coloca justo despus de reset y la NMI en el orden de prioridad y, al igual
que los anteriores dos excepciones, su nivel de prioridad no se puede modificar.

8.2.1.2. Fallo de la gestin de memoria


Esta trampa, como su nombre lo indica, corresponde a un problema de gestin de
memoria y slo puede surgir con el (opcional) la existencia de la unidad de proteccin
de memoria . Como esta unidad no est cubierto en este libro, la captura relacionada
no se desarrollarn ms. Este fallo, al igual que los dos prximos, puede ser inhibida
por el sistema Control de manipulador y registro estatal (SHCSR) del NVIC, vea la
Figura 8.3. Este es el caso en otros lugares despus de un reinicio, desde los
diferentes habilitar todos los bits son 0. De hecho, la
Peso de 16-bit de este registro nos permite autorizar (o bloquear) la transmisin de
este fallo para Cortex-M3 y, por tanto, autorizar (o evitar) su tratamiento especfico.
154 Assembly Language Programming Managing Exceptions 154

Sin embargo, no podemos resolver el problema mediante la inhibicin. Asimismo, el


0 (o 13) bits de peso nos permiten averiguar, como veremos ms adelante en este
captulo, si el tratamiento especfico de la excepcin es activo (o pendiente). Como
estos dos ltimos bits tienen acceso de escritura, es posible desencadenar
artificialmente excepciones estableciendo estos bits a 1. Se recomienda actuar con
prudencia a la hora de hacer esto, sin embargo, salvo en la medida en que el contexto
no siempre est garantizada.

Figura 8.3. Controlador de sistema de control y registro estatal


(NVIC_SHCSR)

8.2.1.3. Fallo de
bus
Con esta trampa, problemas que estn potencialmente presentes en la fase de
desarrollo comienzan a aparecer. Esto corresponde a la imposibilidad para el
procesador para recuperar unprefetch de instrucciones ( Anular) o efectuar la
lectura/escritura de un dato (datos Cancelar). El caso tpico en el que Cortex-M3 cae
en la trampa es que de mala gestin del puntero (y tan indirecto direccionamiento),
donde prcticamente la direccin seal (el contenido del registro de
direccionamiento indirecto) no corresponde a una direccin de datos vlidos. Otro
problema comn es el mal uso de un perifrico que, por ejemplo, intenta recuperar
una palabra de modo que slo puede proporcionar un byte. En ciertos casos,
la BFAR (Bus Fault address Register) conserva la direccin de memoria que ha
producido el fallo. Poco
17 del registro SHCSR nos permite validar o invalidar esta trampa y 14 bits y
1 nos permiten determinar su estado de actividad (activo o
pendiente).
155 Assembly Language Programming Managing Exceptions 155

8.2.1.4. Fallo de uso


Este ltimo fallo, de las cuales un informe sobre qu desencadena es el tema de la
16-bit UFSR, es un fallo que, en contraposicin a un fallo del bus, est ms preocupado
con software de problemas de hardware. Por lo tanto puede ocurrir en la fase de
despliegue (no slo en la fase de desarrollo), por lo que es importante para
proporcionar tratamiento para ti y para ver cmo puede deberse:
- la divisin por cero: En el caso de nmeros de punto flotante, es posible de
normalizar el resultado para devolver un valor correspondiente al infinito. En la
aritmtica de enteros, tal operacin plantea un problema insoluble. Por lo tanto, el
procesador indica este fallo, y enciende el peso de 9 bits () de UFSR DIVBYZERO a
1.
- unalignment: como hemos visto, es posible acceder a datos no alineada. Esta
opcin viene con limitaciones, sin embargo, y cuando nos violan estas limitaciones, la
trampa se activa y el bit 8 (UNALIGNED) est activada. Tambin se activa si el
acceso est prohibido unaligned y ese acceso se intent;
- acceso a un coprocesador: Cortex-M3 set tiene varias instrucciones para un
potencial de coprocesador. Si la unidad no est presente, la respuesta es un fallo de
uso y el bit 3 (NOCP) cambia a 1. Al encontrar este bit, la rutina del tratamiento
pueden ser escritos para ofrecer una emulacin del coprocesador (que nos permite
aumentar la portabilidad del cdigo para diferentes tipos de procesadores).
- imposible volver: aqu esto significa un intento de cargar el contador de programa
(PC) puntero con un valor ilegal durante el regreso de una excepcin. Los detalles de
los valores posibles son dadas en la seccin 8.4. Bit 2 (INVPC) cambia a 1.
- estado no vlido: el T bit de la ejecucin del programa (EPSR Status Register)
nos permite distinguir, en el brazo general arquitecturas, el interruptor de modo de
brazo a modo de pulgar. Como Cortex-M3 slo admite el modo de pulgar, cualquier
intento de cambiar a modo de brazo es sancionado por este fallo con el bit 1
(INVSTATE) est activada. Este problema puede ocurrir accidentalmente por forzar el
valor de PC con un valor (por lo que el bit menos significativo (LSB) est en 0),
durante un salto o procedimiento de retorno (BX LR) por ejemplo. De hecho, en la
codificacin de instrucciones de salto (vase la seccin 5.6) cuando el LSB es 0, el
procesador, as como la rama debe cambiar a modo de brazo, lo cual es imposible para
Cortex-M3.
- Undefined instruccin: el ltimo caso que provoca este fallo es cuando el bit 0
(UNDEFINSTR) est ajustado a 1. En este caso, el PC apunta a una instruccin que
no es decodificable por el ncleo. El caso ms comn es un salto a una direccin que
es vlida, pero no contiene el cdigo correcto (un literal Pool, por ejemplo).

Un fallo de uso puede ser desactivado. Para hacerlo, debemos ajustar el bit 18 de
la SHCSR a 0. 12 y 3 bits de este registro permite el conocimiento del estado de
actividad (activo o pendiente).
156 Assembly Language Programming Managing Exceptions 156

Figura 8.4. Varios registros de estado del fallo (NVIC_MMFSR/NVIC_BSFR/NVIC_UFSR)

8.2.1.5. La trampa SVCall


Esto es normalmente una funcin poner en su lugar a la hora de disear un sistema
operativo o, ms modestamente, un software micro-kernel, permitiendo ms rpido y
despliegue sistemtico de diversas aplicaciones. Una operacin tpica es el uso de un
nmero de serie. Queremos que el usuario sea capaz de transferir datos a travs de este
medio, pero no queremos que l o ella pueda modificar los registros de configuracin
diferentes y as tener acceso a nivel de hardware. El diseador del ncleo podra, por
consiguiente, proporcionar los servicios asociados con esta funcin (enviar/recibir un
carcter) y permitir el uso a travs de una llamada de servicio (SVC) solicitar
al kernel. Esta divisin entre el bajo nivel de servicios y aplicaciones garantiza
la coherencia y la seguridad2.

Esta trampa es llamado por lo tanto en un nivel de software por la instruccin VCS
n, donde n es un valor de <255 (que es inmediatamente codificado) que representa un
ncleo especfico de servicio. Este servicio llamado mecanismo es el mismo para todas
las excepciones. Por lo tanto, sera necesario referirse a la documentacin de este
hipottico kernel para averiguar acerca de los diferentes servicios y cmo utilizarlos.
Es interesante, sin embargo, detenerme en lo que el manejador de esta excepcin
puede hacer para recuperar el valor de n. De hecho, la instruccin codifica el
valor n mediante direccionamiento inmediato, por lo que este valor no se encuentra en
un registro, sino en el propio cdigo. El nico mtodo por el cual podemos recuperar
su

2 mediante el desarrollo de este servicio, es posible construir las dos funciones de "pilares" de
la librera stdio.h (en lenguaje C).
157 Assembly Language Programming Managing Exceptions 157

Codificacin de memoria est recuperando el sptimo datum en la pila del sistema


(vase la seccin 8.4 para guardar el contexto). Esto plantea el problema de saber qu
pila (puntero de pila principal [] o MSP Stack puntero Process [PSP]) necesitamos
trabajar con, y as conocer de qu modo el procesador estaba cuando la excepcin se
activ. Esta informacin est contenida en el valor EXC_RETURN almacenados en el
enlace Registrar (LR) durante el contexto de ahorro. Con este principio establecido,
podemos desglosar Ejemplo 58 en tres pasos:
- eleccin del punto de apilamiento segn el LR prueba;
- Recuperacin de la direccin de almacenamiento de la instruccin que provoc
la excepcin de la primera pila (indirecto);
- Recuperacin del propio cdigo (segundo indirecto).

EJEMPLO 8.4.- tpico de comienzo de un manejador


SVCall

SVC_Handler PROC
Y R0,LR,#0X000F ; En la mscara 4 LSB.
CMP R0, #0x0001 ; Llamada de modo manipulador
BEQ StackMSP
CMP R0, #0x0009 ; Llamada desde el modo de
subproceso
; Con privilegiadas
BEQ StackMSP
CMP R0, #0x000D ; Llamada desde el modo de
subproceso
; Sin privilegio
BNE Salir ; Exec_Return es inidentificables
; ...extrao!
StackPSP La Sra. R0,PSP ; ... usar PSP WWE
B Search_suario
StackMSP La Sra. R0,MSP ; ...utilizamos MSP
Search_suario LDR[R1, R0,#6*4] ; PC puntero es la sptima
guardar
LDRB[R7, R1, #-2] ; Valor inmediato es el
segundo byte

.... ; R7 contiene el valor


pasado n
Salir BX LR ; Volver
ENDP

La SVC instruccin es en realidad codificada en dos bytes. Por ejemplo, SVC 3 se


codifica como la media palabra DF03. El primer byte (0xDF) es el opcode SVC y el
segundo byte es el valor inmediato. Una vez que esta base se coloca en su lugar, todo
lo que queda es
158 Assembly Language Programming Managing Exceptions 158

Para grabar las llamadas a rutinas del kernel correspondientes a distintos servicios
con referencia a una tabla de salto o un If...ElseIf...ElseIf basada en el valor
contenido en R7.

Esta trampa no puede ser enmascarado por cuanto se denomina exclusivamente en


el nivel de software; es completamente sincrnicas y predecible. 15 bits y 7
del SHCSR nos permiten determinar su estado de actividad (activo o pendiente).

8.2.1.6. El monitor
Para llevar a cabo todos los desarrollos y pruebas de una aplicacin determinada,
Cortex-M3 ofrece una estructura de hardware llamado debug. La unidad de
desarrollo tiene la opcin de congelar el ncleo ( modo de parada) y as tomar el
control completo de la ejecucin del cdigo y todas las excepciones (aparte
del restablecimiento y la NMI) que pueden ocurrir. No siempre es posible o deseable,
sin embargo, para congelar completamente el procesador. Por ejemplo, a veces es
conveniente preservar la actividad de ciertas tareas, tales como la aceptacin de nivel
superior patches de excepciones, mientras que el resto del cdigo para supervisar, a
fin de garantizar un mnimo de seguridad.

El segundo mtodo de depuracin, y la que corresponde a esta trampa, puede ser de


gran utilidad. Los diferentes eventos que requieran un interruptor a modo de depuracin
se iniciar la excepcin 12. La escritura de un controlador adecuado (comnmente
llamado un monitor) nos permite tratar correctamente las diferentes peticiones de
depuracin. El bit 8 de la SHCSR nos indica si una excepcin de depuracin monitor
est activo. La activacin/desactivacin del modo de depuracin es posible y es
administrado a nivel de los registros de configuracin de unidades especializadas.

8.2.1.7. El servicio PENDSV


Este servicio tiene una funcin similar a la SVC service. Nos permite, con la
redaccin del controlador correspondiente, para enviar una solicitud a un mayor nivel
de software. Esta segunda opcin existe porque SVC no puede responder en todos los
casos, en la medida en que slo se activa mediante la ejecucin de una instruccin
especfica. Es imposible llamar a esta instruccin de la rutina de tratamiento de una
excepcin que se encuentra en un nivel de prioridad superior. Tal caso causara
un incidente duro. Esta llamada al sistema, por lo tanto, no corresponden a una
instruccin especfica.

La tcnica utilizada consiste en software de conmutacin la excepcin en pendiente


(de ah su nombre) activando el bit 28 del ICSR (Interrupt Control Registro
Estatal), consulte la Figura 8.5. De hecho, en este registro, diferentes excepciones
(SysTick, y NMI PendSV) puede tener pendiente su estado ha cambiado. Cabe sealar
que, por razones de seguridad, el interruptor en modo pendiente y la salida de modo
pendiente se realiza a travs de dos diferentes bits para PendSV y SysTick. La
activacin simultnea de ambos bits es ineficaz. El conmutador a uno de
los (o PENDSTCLR PENDSVCLR) bits tambin borra el PENDSTSET
PENDSVSET (o).
159 Assembly Language Programming Managing Exceptions 159

8.2.1.8. El temporizador SysTick interno


Es responsabilidad del diseador para suministro Controlador de perifricos, y
en particular los necesarios para la medicin y gestin del tiempo. ARM ha decidido
equipar Cortex-M3 con un temporizador llamado SysTick. Esta opcin nos permite
aumentar la portabilidad del cdigo entre los distintos controladores , especialmente
a nivel del kernel en tiempo real. De hecho, esa capa de alto nivel no puede
arreglrselas sin
Un Scheduler, que descansa sobre un temporizador para regular su tarea poltica de
envo. La programacin de este temporizador es el tema del apndice B.

Cuando el temporizador se desborda, excepcin 15 - si se ha validado - se activa y


el bit 11 del registro SHCSR se cambia a 1 cuando la excepcin se convierte en activa.
Como se mencion en la seccin anterior, es posible provocar esta trampa se establezca
en pendiente aunque el bit del ICSR PENDSTSET del NVIC. A la inversa, es posible
terminar el modo pendiente de esta excepcin con el bit PENDSTCLR del mismo
registro.

Figura 8.5. Registro Estatal de Control de interrupcin (NVIC_ICSR)

8.2.2. Interrumpe

Los prximos 239 entradas de la IVT dependen delcontrolador y las opciones


que permite al diseador del circuito. El nmero de interrupcin tambin es variable
dependiendo de la complejidad y la "riqueza" del circuito seleccionado. Como
ejemplo, ya que ha sido
160 Assembly Language Programming Managing Exceptions 160

Criado en el Captulo 1, STM32F103RB utiliza 67 vectores de interrupcin para sus


necesidades internas a nivel perifrico. Estos 67 vectores ocupan las direcciones
0x00000040 a
0x0000014C de la IVT. Por lo tanto, es necesario consultar la documentacin
especfica de cada controlador para conocer y comprender la utilidad de todas estas
interrupciones.

Hay mecanismos que son comunes a todos los diseos, sin embargo: las
interferencias con el NVIC. De hecho como esta unidad recibe y gestiona todas las
excepciones, es normal encontrar dentro de ella registra que slo actan sobre el
comportamiento de los perifricos o, al menos, el comportamiento en el
desencadenamiento de las interrupciones. En primer lugar, hay
el NVIC_ISER[x] (Interrupt Set-Enable registra), que validan la transmisin de estas
interrupciones y en forma simtrica. Entonces hay el NVIC_ICER[x] (Interrupt claro-
Activar registros), que invalida la transmisin. Cabe sealar que, como se ha visto,
para poner las trampas SysTick PendSV y en pendiente, validacin e invalidacin se
producen a travs de distintos bits en registros separados se establece a 1, cuando un
estado binario habra sido suficiente para transcribir esta dualidad. En cada caso el
restablecimiento de bits no tendr ningn efecto y, como un botn, cambiar
un juego (o borrar) a 1 bits se restablecer la clara (o SET) bit del doble registro. El
8 ISERs ocupan las direcciones 0xE000E100 a 0xE000E11C y cada uno de los 32 bits
corresponde a una interrupcin, como se muestra en la Figura 8.6. Una distribucin
completa similar para las rceas entre las direcciones 0xE000E180 yE000E
0x19C corresponde a la invalidacin bits.

Figura 8.6. Interrupcin (NVIC Set-Enable


register_ISER)
161 Assembly Language Programming Managing Exceptions 161

Otros dos grupos de registros, con las mismas caractersticas y rceas ISERs, nos
permiten cambiar el estado pendiente de una interrupcin. Esto involucra el 8
NVIC_ISPER[x] (Interrupcin Set-Pending registra) cambiar a modo de pendiente
(forzando as uno de estos bits en 1 para disparar a travs del manejador de la
interrupcin correspondiente) y los ocho NVIC_ICPER[x] (Interrupt Clear-Pending
registra) para cancelar el modo de pendiente (y por tanto la cancelacin de una
solicitud de interrupcin). Estos dos grupos de registros ocupan las direcciones
0xE000E200 a 0xE000e21c (para ISPER) y 0xE000E280 a
0xE000E29C (para ICPER).

Por ltimo, con el mismo principio de distribucin de bits, podemos utilizar


el NVIC_IASR[x] (interrumpa el estado Activo registra), los cuales tienen acceso de
slo lectura para saber si la excepcin correspondiente est activo (bit a 1) o no (bit 0).
Estos registros se ocupan las direcciones 0xE000E300 a 0xE000E31C.

8.3. Gestin de prioridad

Los eventos que son susceptibles de producir una excepcin generalmente ocurren
en un asincrnico, y por lo tanto, manera impredecible. Es cierto que siempre es
posible activar esos mecanismos, mediante la ejecucin de cdigo; esto es,
naturalmente, el caso de SVC. Es tambin el caso de las interrupciones, a travs de
la ISPERs, pero esta posibilidad sigue siendo bastante atpica. Por lo tanto, es
necesario considerar varias excepciones que ocurren simultneamente, exactamente
en el mismo ciclo de reloj o algunos ciclos de reloj despus, pero lo suficientemente
cerca para que el procesamiento de la primera excepcin no se ha terminado antes de
que comience la siguiente.

ARM ha tenido esto en cuenta y gestin de mltiples es responsabilidad


del NVIC para recibir y organizar las diferentes solicitudes en una jerarqua. Para este
propsito, cada excepcin tiene un nivel de prioridad. Este nivel es un valor para el
cual la prioridad asociada ser mayor cuando el valor es menor. Reset,
NMI y incidente duro tienen sus prioridades fijadas en -3, -2 y -1, respectivamente.
Todas las dems excepciones tienen niveles de prioridad que puede configurarse con
un nmero positivo codificados en 8 bits. El NVIC_SHPR[x] (Prioridad de
administradores del sistema registra, vase la figura 8.7) contienen los niveles
configurables para las trampas y el NVIC_DPI ([x]Registra el nivel de prioridad de
interrupcin, vase la figura 8.8) contienen los niveles programables para las
interrupciones. As configurado, parece que restablecer siempre tiene prioridad sobre
la NMI, que s tiene prioridad sobre el incidente duro, y que es inmutable.

Por otro lado, es responsabilidad del desarrollador para definir el orden de todas
las restantes excepciones, todos estos niveles inicialmente igual a 0 despus de
un restablecimiento.
162 Assembly Language Programming Managing Exceptions 162

Figura 8.7. Prioridad de administradores del sistema de registros (NVIC_SHPR)

Figura 8.8. Prioridad de interrupcin de los


registros (NVIC_dpi)

8.3.1. Los niveles de prioridad y


subniveles

Las figuras 8.7 y 8.8 muestran que los niveles de prioridad se codifican en un byte.
En teora, por lo tanto, hay 256 diferentes niveles de prioridad. Lamentablemente no
es tan simple en la prctica. ARM provee dos sutilezas:
- un diseador puede querer menos niveles, codificado, no slo sobre la base de 8 bits, pero
slo en
3, 4 o 7 bits. Esta eleccin, que no pueden ser modificados por el usuario, se
administra de modo que slo los bits ms significativos (MSB) del nivel son
importantes. As en 3 bits los 8 niveles posibles son 0x00, 0x20, 0x40, 0xE0. En 4
bits, el 16 niveles sera 0x00, 0x10, 0x20, 0xF0. Uno de los problemas de
programacin (pequeo) se refiere al clculo del valor para ser colocado en el registro
con el cdigo de un determinado nivel de prioridad. Un desplazamiento de la
izquierda el nmero de bits necesarios para la codificacin es suficiente para llevar a
cabo esta traduccin. Ejemplo 8.5 muestra las pocas lneas de programacin en el
caso de niveles de codificacin de 5 bits en la rutina de procesamiento asociado
con SysTick;
- la existencia de subniveles: en el NVIC_AIRCR, el campo de 3 bits PRIGROUP
(8 peso a peso 10) nos permite dividir los 8 bits del nivel en dos con el fin de
163 Assembly Language Programming Managing Exceptions 163

Separar la prioridad los niveles y subniveles. Esta separacin - y es aqu donde las
cosas se complican un poco ms, no est relacionada con el nmero de bits elegido
por el diseador para calificar a sus niveles de prioridad; simplemente puede
intervenir con el bit no significativa y, en consecuencia, puede quedar sin efecto.

Las figuras 8.9 a 8.14 ilustrar todas las opciones combinadas resultantes de estos
dos sutilezas. Los bits marcados con una x dar el nivel de prioridad de codificacin y
aquellos marcados con una preocupacin y la codificacin de subniveles. En cada
figura, el valor que debe darse a la
3-bit prio- campo de grupo para definir el nivel deseado/subnivel separacin est
indicada. Cabe sealar que para escribir en el AIRCR, es esencial (para hardware de
seguridad) que la MSBVECTKEY 16 () del valor escrito contiene exactamente
0xFA05, de lo contrario, la escritura no se llevar a cabo. La importancia de los dems
bits del registro es la indicada en la figura 8.15, sin embargo no son directamente
tiles a priori en una programacin comn.

EJEMPLO 8.5.- Ajuste del nivel de prioridad para el


Manejador SysTick

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Ajuste del nivel de prioridad
; para el Manejador SysTick
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LDRB,
R0=0xE000ED23 ; la direccin del registro SHPR
MOV R1,#9 ; 5 bytes de codificacin elegimos un
nivel 9 (sobre 32) aqu
LSL , R1#3 ; => (8-5) Mays izquierda para asignar MSB
STRB R1,[R0] ; Registro de asignacin y para el establecimiento de prioridades

Figura 8.9. La gestin de las prioridades de 8 bits


164 Assembly Language Programming Managing Exceptions 164

Figura 8.10. La gestin de las prioridades de 7 bits

Figura 8.11. La gestin de las prioridades de 6 bits

La figura 8.12. La gestin de las prioridades de 5 bits


165 Assembly Language Programming Managing Exceptions 165

La figura 8.13. La gestin de las prioridades de 4 bits

La figura 8.14. La gestin de las prioridades de 3 bits

Reservado reservado

SYSRESETREQ ha solicitado un restablecimiento


(para su difusin especialmente hacia las unidades de depuracin)
VECTCLRACTIVE poniendo en 1 provoca la supresin de
todos los "estado activo" bits de las excepciones
VECTRESET poniendo en 1 provoca un restablecimiento

Figura 8.15. Registro de gestin de Reset y sub-niveles de prioridad (NVIC_AIRCR)


166 Assembly Language Programming Managing Exceptions 166

8.3.2. El mecanismo anidados

Como ya se ha mencionado, una excepcin puede tener dos estados


diferentes: activo o en estado pendiente. Cuando se genera una excepcin, cambia
automticamente al estado pendiente; el bit correspondiente a la SHCR (trampas) o
ISPER (por las interrupciones), a continuacin, cambia a 1. En un caso normal, es
decir, si se trata de la nica pendiente poco (o si su nivel de prioridad anula otras), el
NVIC cambia la interrupcin al estado activo, el proceso de re-enrutamiento es
lanzado, y se borra el estado pendiente (el bit correspondiente vuelve a 0). La figura
8.16 presenta el calendario para este caso estndar y para los distintos casos
examinados a continuacin:
- Caso No. 1: una prioridad mayor excepcin (A) surge durante la tramitacin de
la excepcin (B): el procesamiento de (B) est interrumpido, pero (B) permanece
activo. El proceso de (A) se puso en marcha y cuando haya terminado (excepcin) la
transformacin de retorno (B) reinicia donde lo dejaste.

La figura 8.16. Principio de excepcin anidada para diferentes niveles de prioridad

- Caso No. 2: una prioridad menor excepcin (C) surge durante la tramitacin de
la excepcin (B): (C) conserva el estado pendiente, y va a pasar a ser activo y ser
procesada cuando el procesamiento de (B) est terminado, salvo una excepcin, con
un nivel de prioridad superior (C) aparece en el nterin.
167 Assembly Language Programming Managing Exceptions 167

- Caso No. 3: al final de la interrupcin (B)'s, el procesamiento de la solicitud es


siempre3. El estado pendiente se cambia a true inmediatamente despus del regreso
de la interrupcin y si ninguna otra excepcin ha aparecido en el nterin, el estado
activo y una nueva ejecucin de la rutina de tratamiento ser validada. Llamamos a
esto una re-entrant interrupcin.
- Caso No. 4: una solicitud (o varios) para peticiones de interrupcin (B) ocurre
cuando el estado de esta interrupcin ya est pendiente (una prioridad mayor,
interrumpir, (A), est siendo procesada). No sucede nada. (B) permanece pendiente y
(A) permanece activo. No hay acumulacin o el apilamiento de las peticiones de
la misma fuente.
- Caso No. 5: una solicitud de interrupcin (B) ocurre cuando el estado de esta
interrupcin se activa. Su estado de pendiente (que fue restablecido durante el
interruptor al estado activo) vuelve a 1. Al final de la transformacin, la interrupcin
directamente vuelve a activo. Tambin llamamos a este una re-entrant interrupcin.
- Caso No. 6: si dos solicitudes de interrupcin del mismo nivel de prioridad, (B)
y (b'), vienen simultneamente, o si ambos han estado pendiente y al final de la
transformacin actual su nivel de prioridad prevalece sobre otros, es la prioridad
subnivel que determina cul de los dos va a cambiar al estado activo. Si tambin
tienen la misma prioridad subnivel, es su nmero de orden que les separa, con
el menor de los supremos. Por lo tanto, si el SysTick (nmero 15) est en el mismo
nivel y subnivel como un fallo de uso (nmero 6) y ambos son capaces de pasar a ser
activo, el fallo de uso tendrn prioridad (6 contra 15), y as se procesa primero.

8.4. Entrada y retorno en el procesamiento de excepciones

El NVIC registros se someten a un cierto nmero de modificaciones durante la


ejecucin de una excepcin, pero esta no es la nica actividad regulada por
el procesador porque debe ejecutar una rutina de procesamiento.

8.4.1. Re-enrutamiento.

Cuando la excepcin pasa al estado activo, el Cortex-M3 lleva a cabo una serie de
operaciones a fin de permitir la ejecucin del controlador especfico. Parte de la re-
secuencia de enrutamiento ya ha sido descrito: la que consiste en la recuperacin de
la direccin donde la rutina se almacena en la IVT. Una vez recuperado, esta direccin
ser modificar el puntero de instrucciones de PC y la rutina ser ejecutado.
Hay otros, sin embargo, las operaciones que se llevan a cabo antes de este salto
asincrnica:

3 Cabe sealar que el bit de peticin de interrupcin no se restablece automticamente


cuando la interrupcin es lanzado. Es la responsabilidad del controlador asociado para realizar
este restablecimiento.
168 Assembly Language Programming Managing Exceptions 168

- ocho registros se almacenan en la pila (MSP si el procesador est en modo


Controlador y, en teora, PSP si est en modo de subproceso: sin embargo, es posible
que el modo de subproceso para utilizar la pila de MSP). Estos registros son, en orden
de apilamiento, PC, PSR, R0, R1, R2, R3, R12 y LR. La pila es originalmente en el
estado que se muestra en la figura 8.17 Al iniciar la rutina de procesamiento;
- el procesador, si no lo ha hecho ya, cambia al modo de controlador. La pila debe
ser MSP durante el procesamiento de excepciones.
- el LR es inicializado con un cdigo de retorno (EXC_RETURN) que le permitir
regresar correctamente desde la excepcin. De hecho en este procesador, en el sentido
contrario a muchos otros tipos de arquitectura, no hay ninguna excepcin instruccin
de retorno. Este retorno se activa cuando el puntero de instrucciones de PC est
cargada con un valor conocido del cdigo de retorno. Este cdigo de retorno nos
permite informar al procesador del modo en el que se debe devolver
(subproceso o controlador) y de manera que la pila del sistema para utilizar
(MSP o PSP). Los tres valores nicos permitidos son los de la tabla 8.1; cualquier otro
cdigo provocar un fallo de uso (el bit UFSR INVPC de ser cambiado a 1).

Figura 8.17. Estado de la pila del sistema despus de una excepcin re-enrutamiento.
169 Assembly Language Programming Managing Exceptions 169

REMARK 8.1.- Es interesante observar que el registro R0 a R3 son aquellos


sistemticamente utilizados por el compilador de C (brazo de RealView). El ahorro
de registro R12 es ms sorprendente y seguramente podran utilizarse para llevar a
cabo el paso de un argumento de interrupciones.

Valor Tipo de
retorno
0xFFFFFFF1 Volver a modo de controlador - la pila es MSP
0xFFFFFFF9 Volver al modo de subproceso - la pila es MSP
0xFFFFFFFD Volver al modo de subproceso - la pila es PSP

La tabla 8.1. Excepcin devolver cdigo almacenado en el LR

8.4.2. Volver

El regreso de la excepcin es, desde un punto de vista de instruccin, muy similar


a la que podamos escribir para provocar un retorno a una clsica rutina. Consiste en
transferir el contenido de LR para el puntero del PC. Esta transferencia se realiza
generalmente por sucursal y eXchange (BX) LR. Como en el caso de llamadas
anidadas (vase la seccin 7.1.2), el LR puede ser alterada durante el proceso de la
rutina de excepcin (por ejemplo, podra llamar a algunas rutinas u otros dentro del
procedimiento de excepcin). Por lo tanto, es esencial guardar LR al inicio del
procedimiento, a fin de restaurarla justo antes de transferirla al puntero de instruccin
con el fin de desencadenar el regreso. Esta restauracin/transferencia puede ser
realizada por una sola instruccin: POP PC. Por ltimo, sealemos que la LDR
instrucciones de carga PC ??? Tambin puede llevar a cabo esta excepcin, sabiendo
que el retorno
??? Debe corresponder a algo (un valor inmediato, un registro, etc.) que contiene uno de
los tres valores permitidos. Cuando el PC recibe este valor de EXC_RETURN, que sabe
en que apilar los ocho registros han sido guardados. Es, pues, en condiciones de llevar
a cabo la restauracin. En el curso de restauracin, luego re-modifica el puntero de
instrucciones de PC con su valor antes de la re-enrutamiento, permitiendo al
procesador para reanudar el curso normal de las ejecuciones desde el lugar donde
fueron detenidos.

8.4.3. "Tail-encadenamiento" y "de


llegada tarda"

En un ciclo de funcionamiento estndar, el tiempo de latencia entre NVIC recibe la


solicitud de interrupcin y el inicio de la primera instruccin de la rutina de
procesamiento de interrupcin es de 12 ciclos de reloj. Tambin puede producir
situaciones en las que dos excepciones siguen unos a otros, en cuyo caso la
restauracin/guardar secuencia pueden funcionar de forma diferente con el fin de
optimizar el tiempo de latencia.
170 Assembly Language Programming Managing Exceptions 170

En el caso de encadenamiento de cola, como en el caso No. 3 (vase la figura 8.16)


implica una excepcin (C) que debe pasar a activo al final de la anterior excepcin (B).
En este caso es intil para realizar la restauracin al final de la letra b) y, a
continuacin realizar inmediatamente el guardar para lanzar (C), ya que no haba
registro modificacin entre los dos puntos. Este doble secuencia es, por lo tanto,
omitir. A la hora de regreso de (B), el procesador pasa directamente a la
transformacin de la (C) y restauracin slo tiene lugar en el regreso de (C). En este
caso, el conmutador de (B) a (C) toma solamente 6 de los 12 ciclos necesarios sin
este "truco".

El caso de llegada tarda implica una prioridad mayor excepcin (A), que se
produce cuando el re-direccionamiento secuencia de una excepcin de nivel inferior
(B) ya ha comenzado. Esto podra corresponder al caso No. 1 por avanzar en el flanco
de la solicitud (A) de modo que tiene lugar justo despus de que (B) pasa al estado
activo. Aqu tambin el tiempo de latencia puede ser optimizado por no realizar un
doble guardar; es decir, al no iniciar una secuencia despus de guardar (A), desde el
punto de guardar es el mismo (B). (A) sern sustituidos por (B) en el re-enrutamiento
y (B) se cambiar a PENDIENTE. Al final de la letra a), salvo excepciones han surgido
con mayor prioridad, un mecanismo de encadenamiento de cola ser implementada
con el fin de reanudar el re-direccionamiento de (B).

8.4.4. Otros registros tiles para el NVIC

Como hemos visto en el curso de este captulo, el NVIC module es el verdadero


conductor para la organizacin de un controlador de excepciones en una jerarqua. Para
completar nuestra cuenta de su potencial, hay algunos registros de izquierda a explicar.

PriMask FaultMask BasePri , y son tres registros bsicos; por lo tanto, no ocupar
una direccin de memoria. No son parte del NVIC, pero su papel es, sin embargo,
directamente vinculada a la gestin de excepciones. stas se describen en la
documentacin especial porque no son directamente accesibles. Para acceder a ellos,
el cdigo debe utilizar las instrucciones especiales Sra. (pasar de Registro especial)
para la lectura y el MSR (Mover a registro especial) para escribir, consulte el Captulo
5. Estas dos instrucciones requieren privilegios para ser ejecutado.

Los registros y cada FaultMask PriMask slo tienen una significativa en 0 bits.
As, cuando la lectura, el 31 de MSB son siempre en 0 y, simtricamente, escribiendo
a estos bits no tendr ningn efecto. Estos dos registros, como su nombre indica,
permiten enmascarar las excepciones. Cuando el LSB es de 1 en FaultMask, sin
excepciones, aparte de la excepcin de NMI, cambiar a estado activo y, si una
solicitud interviene, permanecer en estado pendiente. Tan pronto como el bit es
restablecer, pendiente excepciones cambiar a un estado activo siguiendo el orden de
sus respectivas prioridades. Es idntico a FaultMask PriMask, con la diferencia de
que adems de NMI tambin permite la puesta en marcha de la tercera excepcin con
un nivel de prioridad no configurables, a saber, un duro fallo.
171 Assembly Language Programming Managing Exceptions 171

Prohibir a todos (o casi todos) las posibles excepciones que pueden ser tiles en
situaciones "catastrficas" para el que un kernel en tiempo real va a cambiar el
procesador a un "cuasi" modo degradado que esperamos proveer soluciones a estas
situaciones.

BasePri es similar. Esto implica un registro de que los ocho LSBs puede ser
significativo. En efecto, contienen una mscara en el mnimo nivel de prioridad de las
excepciones que podran cambiar a estado activo. Todas las excepciones con un nivel
de prioridad inferior quedara pendiente. Esta configuracin de registro 0x00 es
equivalente a la ausencia de la mscara. Dos pequeos escollos debe evitarse para
ajustar BasePri. En primer lugar, debe recordarse que la escala de prioridad es el
inverso de la numeracin normal (nivel 3 es inferior al nivel 2). Entonces, como se
podra hacer para ajustar las prioridades en los registros asociados (ver ejemplo 8.5),
no se debe olvidar efectuar los 8 - n desplaza a la izquierda del valor deseado si el
procesador slo cdigos de niveles de prioridad de n bits.

El NVIC_revuelva desencadenar el registro de interrupcin ( Software) es el


ltimo registro de NVIC que consideraremos aqu. Este registro (@ 0xE000EF00) es
una alternativa al uso del NVIC_ISPER registrarse, ya que al escribir un valor en el
LSB (INTID) esto asciende a interrumpir INTID conmutacin en estado pendiente. En
una aplicacin para emular el desencadenamiento de una interrupcin con el
software, este segundo camino ser, sin duda, ms rpido y ms prctico de
implementar.
Captulo 9

En la lista de ejecutables:
modularidad externo

En el contexto de desarrollo nativo, el sistema informtico sobre el cual se ha


aplicado un proyecto se desarrolla es exactamente el mismo que ejecutar el proyecto.
Cuando escribimos un programa para un controlador , esto nunca es el caso: de hecho,
no hay ningn programa en Cortex-M3 que nos permite desarrollar otro ejecutivo para
Cortex-M3. El programador se encuentra en una situacin de desarrollo cruzada
donde la escritura y la generacin de un archivo ejecutable se realiza en un sistema
informtico central y la ejecucin se transporta al objetivo determinado hardware.
Puede haber una sutileza en este esquema bsico, sin embargo, que es el uso de un
emulador que nos permite desarrollar un proyecto sin un objetivo real. Este emulador
es un programa que funciona en el host
Sistema y simula el funcionamiento del controlador -ciclo por ciclo, instruccin
Por instruccin. Aunque hay excelentes los emuladores que son capaces de replicar
de forma muy precisa el funcionamiento interno de un procesador, no es raro
encontrar diferencias cuando se ejecuta en un procesador real y la fase final de
validacin no pueden ser llevadas a cabo sin las pruebas en un objetivo real.

En el transcurso de la fase de desarrollo, la cruzada entre escribir el cdigo en una


(o varias) "listado" archivo(s) y la ejecucin de este cdigo en un procesador
determinado, hay distintas etapas (y, por lo tanto, herramientas diferentes), cada una
de las cuales es necesaria para la correcta realizacin del conjunto. Estos son:
- el ensamblador, que interpreta una fuente lista para crear un archivo objeto;
- el vinculador, que rene los diferentes objetos del proyecto y partes de la
biblioteca para hacer el archivo ejecutable;
174 Assembly Language Programming
From Listing to Executable: External Modularity 174

- un cargador, que transfiere el ejecutable en la memoria de la tarjeta (o en el


emulador, si es que hay alguno).
- un depurador simblico, que, como mnimo, permite el arranque y parada de la
ejecucin en el destino, sino tambin, como el nombre lo sugiere, busca posibles
errores en la aplicacin creada.

La figura 9.1 muestra cmo las diferentes herramientas pueden ser conectados uno al otro.

Figura 9.1. Sinptico del brazo toolchain

Para Cortex-M3-basado controladores, hay muchos toolchains que pueden


funcionar en Windows o Linux. Consulta las herramientas de desarrollo de software
- pginas en el sitio web de brazo nos da una idea de la paleta de opciones y
las dificultades que puede
175 Assembly Language Programming
From Listing to Executable: External Modularity 175

Ocurren, incluso antes de haber escrito una lnea, para elegir la mejor herramienta
para sus necesidades y prcticas.

Este captulo, al igual que las otras partes de este libro y, especialmente, el captulo
3 de las directrices de la asamblea, utiliza el Keil-ARM-MDK (Kit de desarrollo de
microcontroladorKEI ) [cadena], que es armar la propia
1
herramienta . Algunos elementos de la GNU (GNU no es UNIX) cadena figuran en
el Apndice D. Este captulo slo est interesada en los principios bsicos de los
diferentes instrumentos aplicados en una cadena de desarrollo transversal, por lo que
la transposicin a otro producto puede hacerse sin mucha dificultad.

REMARK 9.1.- En el curso de este captulo, las explicaciones sern limitados a


aquellos que son tiles para la comprensin de cmo la cadena de desarrollo de
producto para construir un simple ejecutable. Esto implica que el cdigo es absoluta
y no puede ser reubicado. Conceptos avanzados tales como dynamic vinculadores, por
ejemplo, no se abordan.

Volvamos ahora al concepto de modularidad presentados en el Captulo 7,


examinando lo que ocurre cuando los mdulos que componen el programa estn
repartidos en varios archivos (modularidad) externo.

9.1. Modularidad
externo

9.1.1. Ejemplo
genrico

A fin de exponer con mayor claridad los diferentes puntos abordados ms


adelante en este captulo, vamos a utilizar un ejemplo sencillo. El proyecto cuya
arquitectura general aparece en la figura 9.1 se compone de cinco archivos:
- STM32F10x.s es un archivo suministrado por el entorno de desarrollo de Keil.
Contiene, entre otros, una reserva e inicializacin de la pila del sistema, una
declaracin de los diferentes vectores de interrupcin y el mnimo de rutinas (limitada
a un solo bucle infinito) para los controladores de excepciones ms crticos;
- un recurso.lib biblioteca que contiene una serie de rutinas de entrada/salida,
dependiente de hardware y inaccesibles para el desarrollador en formato fuente;
- un proyecto.sct descripcin archivo de memoria;
- dos archivos "fuente", escrito en lenguaje ensamblador: Principal.s (ver ejemplo
9.1) y CallProc.s (ver ejemplo 9.2).

Todo este proyecto es de inters algortmico restringidos. El uso de variables


globales y optimizacin de cdigo podra ser examinado en detalle, pero tal y como
es, nos permite

1 Desde el 2005 la recompra de Keil por el brazo.


176 Assembly Language Programming
From Listing to Executable: External Modularity 176

Para ilustrar el objetivo de este captulo tan simplemente como sea posible. Este
proyecto consiste en el clculo del promedio ponderado de dos nmeros de la
siguiente manera:

(Val 1 Coef ) (1) + (Val2 Coef (2)


R = esu
(Coef (1) + Coef (2)

Las dos palabras de media Val1 y Val2 son ledos por una rutina de biblioteca de
recursos y se declaran, como resu, que almacena el resultado en una seccin de datos
del mdulo principal Principal.s. Coef byte es la tabla de los dos elementos declarados
en una seccin de datos del mdulo CallProc.s.

EJEMPLO 9.1.- Listado de los principales mdulo.s

;//**************************************************************
pulgar
;//**************************************************************
Importacin/Exportacin ;
;//**************************************************************
importar ||LibRequestarmlib|| [Cdigo,dbil]
Importar Ave_Weight
importar ReadData
principal exportacin
Exportar Val1
Exportar Val2
Exportar Resu
;//**************************************************************
; Seccin de datos
;// AREA************************************************************** mydata,
datos readwrite
Val1 espacio 2
Val2 espacio 2
Resu DCW 0
;//**************************************************************
; seccin de cdigo
;//**************************************************************

Mycode, cdigo de rea, readonly


177 Assembly Language Programming
From Listing to Executable: External Modularity 177

Principales PROC
LDR, R0= Val1
BL ReadData ; lee primero los datos
(Val1)
LDR, R0= Val2
BL ReadData ; segunda lectura de
datos (Val2)
BL CallProc
Infinito B infinito ; Fin del programa
ENDP

Final ; Fin del mdulo

EJEMPLO 9.2.- Inclusin del mdulo CallProc.s

;//**************************************************************
Importacin/Exportacin ;
;// exportacin**************************************************************
Ave_Weight
Importar Val1
Importar Val2
Importar Resu
;// AREA************************************************************** mydata,
datos
Coef DCB 8,12 ; coeficientes fijos
;// AREA************************************************************** mycode,
cdigo
Ave_Weight PROC
LDR R0, =Val1
LDRH R4,[R0]
Ponderacin LDR R0, =Coef
LDRB R2,[R0]
MUL R4,R2 ; Ponderacin de Val1
LDR R0, =Val2
LDRH[R5, R0, R0]
LDR =Coef LDRB[R3,
R0, #1]
MUL R5,R3 ; Ponderacin de Val2
Suma
178 Assembly Language Programming
From Listing to Executable: External Modularity 178

Agregar R4,R5
Agregar R2,R3
Promedi
o
UDIV R4,R2 ; el clculo de la media
LDR R0, =Resu
STRH R4,[R0] ; el almacenamiento del resultado
BX LR
ENDP
END ; Fin del mdulo

9.1.2. Montaje de piezas

Nuestro ejemplo se compone de tres archivos de "fuente", a la que tambin


llamamos mdulos. Esto puede ser confuso, pero el uso de este trmino es anterior a
la programacin modular completamente, y no ha cado en desuso. En el siguiente
mdulo, cuando decimos que significa separado archivo (mdulo externo) y no de
procedimiento, que define la modularidad interior como se discuti en el Captulo 8.
Las declaraciones e instrucciones de un programa, por lo tanto, se puede dividir a
voluntad en varios archivos, mientras que la sintaxis es respetada. En particular,
cualquier seccin de cdigo o de datos se cerrar con el final del mdulo o mediante
la apertura de un nuevo mdulo. De manera similar, cualquier procedimiento abierto
ser cerrado (ENDP directiva) en un mdulo. El ensamblador es capaz de traducir
individualmente cada mdulo en lenguaje de mquina, que podemos llamar asamblea
por piezas. El vinculador grupo posteriormente el objeto resultante de mdulos en un
todo coherente en la forma de un archivo llamado un archivo ejecutable (o ms
precisamente loadable para su ejecucin).

9.1.3. Ventajas de montaje por piezas

Ensamblado independiente presenta algunas ventajas interesantes2:


- prueba individual: cada mdulo que est acompaado por un mdulo de prueba
pueden ser probados individualmente. Si cada mdulo trat por separado funciona,
podemos esperar que la versin final que rene todos los mdulos tambin
funcionarn. Por el contrario, si un mdulo no funciona el proyecto como un todo no
puede responder correctamente a todas las especificaciones.
- Localizacin de las consecuencias de una modificacin: la modificacin de un
mdulo slo afecta a la re-ensamblaje de este mdulo seguida por la llamada al
vinculador;
- Recuperacin de un mdulo: podemos reutilizar un mdulo en otro programa.

2 Estas diversas observaciones son vlidas tambin para el compilador.


179 Assembly Language Programming
From Listing to Executable: External Modularity 179

- reacin de bibliotecas: podemos crear bibliotecas de funciones de utilidad (input-


output, punto flotante o clculos complejos, funciones trigonomtricas, transcendents
hyperbolics, elpticas, y otros);
- Distribucin y copyright: podemos distribuir bibliotecas de procedimientos y
datos en forma de mdulos de objeto sin proporcionar el programa de origen.

9.1.4. Smbolos externos

Cules son las consecuencias si nuestro programa est escrito en piezas? Para
responder a esta pregunta, es necesario analizar las relaciones entre los mdulos del
programa, a fin de comprender la necesidad de directivas presentadas posteriormente.

Generalmente, un mdulo puede contener cdigo y datos, que son colocados en


una o ms secciones, como son los smbolos (seccin nombres, los nombres de
procedimiento y etiquetas). En nuestro proyecto, cada uno de
los principales.s y CallProc.s archivos contienen una seccin de cdigo y una seccin
de datos.

Las instrucciones que contiene el mdulo puede referirse no slo a los datos o
procedimientos ubicados en el mismo mdulo, sino tambin para datos o
procedimientos3 definido en otro mdulo. En un lenguaje de alto nivel, hablamos de
importar datos o procedimientos. El principal.El mdulo de llamadas (y por lo tanto las
importaciones) el Ave_Weight procedimiento desde el CallProc.s y el mdulo de la
biblioteca ReadData resource.lib procedimiento. Simtricamente,
la CallProc.s archivo utiliza el Val1 Val2 y Resu variables declaradas en el mdulo
principal.s. Tales referencias son, por tanto, llamado mdulo externo referencias.

En todos los casos, el ensamblador, al llevar a cabo la traduccin de un mdulo en


particular, no conoce el contenido de otros mdulos. Es, por lo tanto, no se puede
atribuir un valor numrico para el smbolo (una direccin o datum) interesados en la
palabra de cdigo que representa la instruccin.

Cuando lee el anuncio, el ensamblador elaborar una lista de los smbolos, que se
divide en tres categoras:
- smbolos absolutos: estos son los smbolos cuyo valor asociado
es totalmente definida en el listado. Normalmente, estos son constantes
(directiva EQU). Cuando el ensamblador encuentra este smbolo, puede resolverlo sin
ambigedad y determinar el cdigo de word para ser almacenados en la memoria.
- smbolos reubicables: estos son smbolos pertenecientes al mdulo actual, pero
cuyo valor numrico no puede ser determinada. stas son variables inicializadas o

3 Este es el mismo para la sucursal de instrucciones.


180 Assembly Language Programming
From Listing to Executable: External Modularity 180

De lo contrario, que se declaran en una seccin de datos del mdulo, y las etiquetas o
los nombres de procedimiento de una seccin de cdigo. En todos los casos los
smbolos corresponden a direcciones. A nivel de construccin de programa, el
ensamblador slo puede darles un valor relativo. Esto permite que el ensamblador para
encontrarlas en la seccin donde fueron declarados;
- smbolos externos: estos son los smbolos que no pertenecen al mdulo y a que
el ensamblador no puede dar ningn valor. Cuando se utiliza este tipo de referencia
externa en un mdulo, es necesario indicar al ensamblador que el smbolo afectado
est definida en otro mdulo. En la ausencia de esta indicacin, el ensamblador va a
considerar que se trata de un smbolo no definido y producir un mensaje de error.
Esta directiva es la directiva import.

La fase de montaje de CallProc.S localiza los smbolos presentados en el Ejemplo

9.3. Incluso si no aparece claramente, un cierto nmero de informaciones son


Asociado con esta tabla: la pertenencia de una seccin en particular y los lugares
Donde los smbolos utilizados. Tomamos nota de que si es imposible atribuir un valor,
el ensamblador dar el valor 0 a un smbolo externo. Tambin cabe sealar que los tres
smbolos ponderacin, Suma y Promedio no tienen uso algortmico en la medida en
que son etiquetas que no se usan en las instrucciones, ya que slo juegan el papel de
los comentarios. Sin embargo, el ensamblador encuentra y los sita como otros
smbolos, sino que tambin registra esta caracterstica de no-uso. Posteriormente, si
los datos son todava no utilizados, no podrn ser almacenados en la tabla de smbolos
a menos que sea solicitado explcitamente marcndolas como tales con la directiva
(vase la seccin 3.5.2).

EJEMPLO 9.3.- lista smbolo situado en el mdulo CallProc.s

Smbolos reubicables
Coef 00000000
Ave_Weight 00000000
0000001C ponderaci
n
media 0000000E Sum
a 00000018
Smbolos externos
Resu 00000000
Val1 00000000
Val2 00000000
181 Assembly Language Programming
From Listing to Executable: External Modularity 181

9.1.5. Importar y exportar directivas

Visto desde el exterior, cada mdulo por defecto se comporta como una caja negra,
con sus propios recursos y smbolos. A priori sus smbolos no son accesibles por otros
mdulos. Esto evita cualquier interferencia exterior dentro del mdulo. Sin embargo,
debemos considerar el caso de un mdulo que contiene ciertos smbolos para ser usado
por uno o ms mdulos. Estos smbolos, llamados bienes exportables, deben marcarse
explcitamente como tales porque, de forma predeterminada, los smbolos definidos
en un mdulo son privados, lo que significa que son visibles slo en ese mdulo. El
alcance de los smbolos exportables (equivalente a la visibilidad en lenguaje
ensamblador) es global, a diferencia de los smbolos privados cuyo alcance es slo
local. Por lo tanto, cualquier smbolo slo puede ser privado o exportables (global).

Hay dos directivas para establecer estas propiedades de visibilidad. La posicin de


estas directivas en el mdulo es gratuito, pero la convencin es colocarlos en la cabeza
porque simbolizan la interfaz con el mundo exterior.

La primera, la exportacin, nos permite informar el ensamblador y el enlazador


que el smbolo definido podra fusionarse con un smbolo idntico utilizado en otro
mdulo. La existencia de esta directiva indica que la visibilidad de un smbolo
determinado est limitado por defecto en el propio mdulo. En otras palabras, cuando
se nombre un nuevo smbolo no es necesario preocuparse por su posible existencia en
otro mdulo. La sintaxis es como sigue:

Smbolo de exportacin [dbil,tipo]

La opcin dbil especifica si el smbolo est definido en otro lugar (en el mdulo
actual o en cualquier otro mdulo); esta definicin sern priorizados para la
exportacin. Esta opcin se utiliza para la declaracin de smbolos asociados con
excepcin de vectores (ver ejemplo C.1 en el Apndice C). Por lo tanto, es posible que
el desarrollador para reescribir un controlador de excepciones: su nombre debe ser
reconocido correctamente a fin de modificar la tabla de vectores de interrupcin sin
entrar en conflicto con la rutina escrito por defecto.

La opcin type nos permite especificar, si es necesario, si los smbolos deben


tratarse como un dato (tipo ser entonces datos) o como cdigo (tipo ser entonces
el cdigo). Por defecto, el ensamblador elige el tipo que parece mejor adaptado
simplemente copiando el tipo de la seccin en la que se declara.

La importacin puede ser substituida por EXTERN; estas dos directivas son casi
totalmente equivalentes. Con la directiva extern, un smbolo slo ser incluida en la
tabla de smbolos si se utiliza en el mdulo. Como resultado, por ejemplo, si el
smbolo
182 Assembly Language Programming
From Listing to Executable: External Modularity 182

VarForgot es declarado en un proyecto y no se utiliza en el cdigo del mdulo actual,


la directiva import VarForgot generar un error del vinculador, pues todava
estar incluido en la lista y por lo tanto buscado por el vinculador. Por el contrario, la
directiva EXTERNE VarForgot no har nada y, por lo tanto, el vinculador no
preocuparse de no encontrarla.

La directiva import realiza la funcin inversa de la anterior directiva: permite que


el ensamblador para saber si ese smbolo calificado proviene de un mdulo externo. Si
este es el caso, se puede aceptar el uso del smbolo en el cdigo del mdulo.

Smbolo de importacin [dbil,tipo]

La opcin type tiene el mismo significado que tiene en la exportacin de directiva.

En la ausencia de la opcin dbil sobre un smbolo, si el enlazador no puede


reconocer el smbolo (es decir, si el smbolo no existe en otras partes del proyecto),
provocar un error fatal en la construccin del proyecto. Por el contrario, si el smbolo
est marcado como dbil durante su importacin, el vinculador siempre sern capaces
de resolver el smbolo, dndole un valor predeterminado, si hay alguno. Si el smbolo
es un destino (smbolo B, por ejemplo), su valor por defecto ser la direccin de la
siguiente instruccin. El salto ser equivalente a NOP (No Operation). En otros casos,
el valor predeterminado ser
0. Mal uso controlado de la debilidad en las importaciones de una variable puede
ser peligroso.

Como un ejemplo, imaginemos olvidando las exportaciones de Resu en el archivo


principal.s y la confirmacin de este mismo smbolo por dbiles en CallProc.s. Esto
dara como resultado un proyecto que fue construida correctamente, pero el resultado
ser almacenado en la direccin de memoria 0x0000000! Entonces debemos esperar
que un reset no ocurrir despus, desde la direccin de la pila ya no sera vlido
(vase la seccin 8.1). Como la directiva extern para importar, la directiva de
exportacin pueden ser sustituidos (con ninguna sutileza de utilizar en este caso) por
la directiva global.

9.2. La funcin del ensamblador

La principal funcin del ensamblador es traducir el contenido del mdulo de cdigo


fuente escrito en lenguaje ensamblador, en palabras de cdigo en lenguaje mquina (que
debemos recordar son codificadas en 16 o 32 bits). No es capaz de realizar un trabajo,
sin embargo, porque carece de una serie de datos: no se conoce el valor de smbolos
externos, ni la direccin donde cada seccin definida en la fuente ser colocado. Sin
embargo, es capaz de llevar a cabo su trabajo. Vamos a ver cmo
183 Assembly Language Programming
From Listing to Executable: External Modularity 183

Producto y cmo se prepara el trabajo para el vinculador, que terminar la


formacin del programa.

9.2.1. Los archivos producidos por el ensamblador

El ensamblador principalmente produce dos archivos (vase la figura 9.1): El


archivo objeto binario (.obj), que ser utilizado por el vinculador, y una lista de
archivos.lst () para su utilizacin por el desarrollador que quiere ver el resultado de la
labor del montador4. Ejemplo 9.3 era una pequea parte de un "" Listado de archivo
.lst. Ejemplo 9.4 muestra otro extracto, ms centrado en la traduccin de las diferentes
secciones del principal.s archivo de origen.

EJEMPLO 9.4.- Extracto de los principales.lst

10 00000000 ;**********************************************
11 00000000 Importacin/Exportacin ;
12 00000000 ;**********************************************
13 00000000
14 00000000 Importar ||LibRequestarmlib|| [cdigo] DBIL
15 00000000
16 00000000 Importar Ave_Weight
17 00000000 Importar ReadData
18 00000000
19 00000000 Principal exportacin
20 00000000 Exportar Val1 [CODE]
21 00000000 Exportar Val2
22 00000000 Exportar Resu
23 00000000
24 00000000 ;**********************************************
25 00000000 ; Seccin de datos
26 00000000 ;**********************************************
27 00000000
28 00000000 rea myData, datos readwrite
29 00000000
30 00000000 00 00 Val1 espacio 2
31 00000002 00 00 Val2 espacio 2

4 hace mucho tiempo en la ciencia de la computacin, antes toolchain exista, era a travs de la
lectura de este archivo que el desarrollador podra conocer los errores que se detectaron por el
ensamblador y donde estaban ubicados.
184 Assembly Language Programming
From Listing to Executable: External Modularity 184

32 00000004 10 00 Resu DCW 0x10


33 00000006
34 00000006 ;**********************************************
35 00000006 ; seccin de cdigo
36 00000006 ;**********************************************
37 00000006 Mycode, cdigo de rea, readonly
38 00000000
39 00000000 principales PROC
40 00000000
41 00000000 4804 LDR, R0= Val1
42 00000002 F7FF FFFE BL ReadData
43 00000006 4804 LDR, R0= Val2
44 00000008 F7FF FFFE BL ReadData
45 0000000C
46 0000000C F7FF FFFE BL Ave_Weight
47 00000010
48 00000010
49 00000010 E7FE Infinito B Infinito ; Fin del programa
50 00000012
51 00000012 ENDP
52 00000012
53 00000012 END ; Fin del mdulo
0000
0000 0000
0000 0000

Cuando el ensamblador ha completado su labor, el fruto - que ser utilizado ms


tarde por el vinculador - es un archivo objeto en cdigo ejecutable y vinculacin ELF
( formato). Este formato fue originalmente creado por y para UNIX. La codificacin
es binaria (y por lo tanto no visible directamente utilizando un editor de texto clsico)
y ensamblado contiene cdigo que puede haber sido previamente compilado (objetos,
ejecutables y bibliotecas de funciones).

Codificacin en ELF es nico, pero su contenido ser significativamente diferente


dependiendo de si se trata de un archivo de entrada a un vinculador o si es un archivo
ejecutable para un sistema operativo. Consideremos el primer caso. El archivo ELF
comienza con un encabezado seguido por un conjunto de secciones. Partes de las
secciones ELF que encontramos en este archivo corresponden a secciones declarados
en la fuente ensamblador. Estas secciones se completaron con otras secciones que
contienen informacin que permite la consecucin de
185 Assembly Language Programming
From Listing to Executable: External Modularity 185

La construccin de la imagen ejecutable del proyecto. Podemos citar que contiene la


tabla de smbolos (vase la seccin 9.2.3) o aquellos que se dedican a la relocalizacin
de tablas (vase la seccin 9.4) como ejemplos de secciones. Por ltimo, otras
secciones son opcionales, como las que agrupan los datos necesarios para el
funcionamiento de un depurador (vase la seccin
9.4).

REMARK 9.2.- existen programas especficos para la lectura de archivos codificados en


formato ELF, a fin de recuperar y ver informacin relacionada con su contenido. En
el desarrollo del brazo de cadena, esta herramienta se corresponde con el archivo
ejecutable del programa FROMELF.

9.2.2. Contadores de
colocacin

El ensamblador realiza todos sus trabajos de una manera relativa. Para cada
mdulo se numera cada lnea, como se puede ver en la primera columna de ejemplo
9.4. Esta primera bsqueda no es muy complicado, ya que consiste en localizar
el retorno de carro de caracteres ASCII en el listado de procesados. Sin embargo,
cabe sealar que tambin se encuentran en lneas vacas, un detalle importante para un
sistema de desarrollo que debe indicar la lnea donde se encuentra un error o para el
desarrollo cuando el anuncio se coloca en paralelo con el cdigo desensamblado. Para
cada seccin, ya que es cdigo o datos - el ensamblador tambin utiliza un contador de
colocacin (la segunda columna de la lst ) cuyo valor inicial es 00000000. La direccin
de la salida de cada seccin se fij provisionalmente en 0. En el caso de una seccin
de cdigo, en la medida en que lleva a cabo su traduccin, el ensamblador aumenta el
valor del contador de colocacin por 2 4, dependiendo del tamao de la instruccin.
El contador de colocacin, por lo tanto, indica la posicin relativa de cada instruccin.
Funciona de la misma manera para cada seccin de datos, el incremento de su contador
interno dependiendo del tamao de la variable.

Para cada nueva seccin, el contador se reiniciar la colocacin en 000000. Si una


seccin est cerrada, pero se abre una segunda vez en el mismo archivo de cdigo
fuente, la colocacin contador no se restablece a 0 pero contina desde el ltimo valor,
lo que de facto significa la mitad de la concatenacin de dos secciones.

9.2.3. Primer paso: tabla de


smbolos

Clsicamente un ensamblador trabaja en dos pasadas. En la primera pasada,


explora todo el texto para plantear todos los smbolos y establecer una tabla de
smbolos. Ya hemos mostrado cmo esta tabla fue presentada en el ejemplo 9.3, sin
embargo, hay otro elemento importante que se aade: el literal de las zonas de piscina.
De hecho, cuando un ensamblador escanea todas las instrucciones que componen el
cdigo, localiza las direcciones (siempre en forma relativa) de la seccin analizada
donde ser posible almacenar
186 Assembly Language Programming
From Listing to Executable: External Modularity 186

Valores inmediatos que debe estar codificado en 32 bits en esas zonas especficas
(vase la seccin 4.2.2.3). El ensamblador por lo tanto proporciona las reservas
necesarias por insertar lneas en los lugares as determinado. Estas lneas, en la medida
en que recibir an sin resolver (reubicable datos smbolos), se rellenan con 0s en el
primer pase. En el ejemplo 9.4 hay dos instrucciones para cargar el registro R0 con las
direcciones de Val1 (lnea 41) y Val2 (lnea 43). Estas dos instrucciones
sern codificadas como la lectura del contador de programa (PC) con relativa
indirecto hacia la zona de la piscina literal, una zona de 10 bytes inicializadas a 0 que
podemos ver justo despus de la lnea 52. En el presente caso, dos bytes de relleno se
han agregado a aquellos que son efectivamente necesaria para alinear el literal de
la zona de piscina con un doblemente siquiera abordar.

Para evaluar las etiquetas que busque las instrucciones, en el curso de la primera
pasada el ensamblador examina los operandos de las instrucciones y deduce la longitud
de la palabra de cdigo mediante la traduccin de las instrucciones. Esto nos permite
calcular el valor (que es siempre relativa) de la colocacin de la siguiente instruccin:
el valor de la etiqueta es que la colocacin actual del contador. Este valor no
es definitivo, pues la seccin comienza en 0. El valor real de la etiqueta slo se
conocer despus de la colocacin de memoria (reubicacin) por el linker: las
etiquetas son, por tanto, necesariamente reubicable.

9.2.4. Segundo paso:


traduccin

Durante el segundo paso, el ensamblador realiza la traduccin mediante los valores


de la tabla de smbolos.

Por smbolos externos, se utiliza un valor que slo puede ser provisional, ya que, en
el mejor de los casos, slo se sabe que el seguimiento de la labor del vinculador.

En el caso concreto se muestra debajo de la carga de un valor inmediato a travs


de una zona de piscina literal, la codificacin de la instruccin es exacto y definitivo.
De hecho, el ensamblador determina la zona donde el valor inmediato, codificada en
32 bits, ser almacenado. Acceso a los datos ser relativo al valor de la PC. As, en la
lista podemos ver que la instruccin LDR R0, =Val1 est codificada como 4804. En
observando el principio de codificacin de la LDR instruccin (ver ejemplo 9.2), el bit
ms significativo (48) tambin es el opcode de la instruccin seguida por los 3 bits
000 a cdigo R0. El valor inmediato imm8 aqu es 0x04, por lo que el desplazamiento
para llegar a la piscina es literal, por lo tanto, 4*4 = 16 bytes. Este valor relativo luego
nos permite consultar un direccionamiento indirecto acceso por [PC,#16]. Cabe
sealar sobre el listado, sin embargo, que el posicionamiento relativo de la piscina es
literal en 0x00000012, y por lo tanto tiene un diferencial de 18 bytes. Por lo tanto, hay
una diferencia de dos bytes causada por la existencia de una canalizacin, lo que
implica que el valor del equipo en el momento de la ejecucin real de la enseanza
ser diferente al valor de que donde la instruccin se almacena.
187 Assembly Language Programming
From Listing to Executable: External Modularity 187

Para las referencias a etiquetas internas, el ensamblador se utiliza el valor de la


etiqueta dada por su tabla de smbolos. En algunos casos, como en el caso de Salta,
por ejemplo, la codificacin en relacin con el operando es posible. As, la traduccin
es directa. Para las referencias a etiquetas externas, la codificacin no es nunca posible
directamente hasta el punto de que la etiqueta est sin resolver. El ensamblador, por lo
tanto, introducir un cdigo operando parcialmente falsa que pertenecern al
vinculador, a fin de dar el valor correcto. En nuestro ejemplo, el salto a
la ReadData (lnea 42) El procedimiento es codificado como 0xF7FFFFFE. Los
primeros 7 bits corresponden tambin al opcode de la BL (sucursal con Link)
instruccin (11110), pero el resto de 23 bits no permiten la decodificacin de una
subrutina vlido direccin en este estado. En este caso estamos tratando con una
instruccin codificada que debe ser "trasladados" por el vinculador.

Figura 9.2. Codificacin de un pulgar instruccin LDR

9.2.5. Tabla de reubicacin

Por ltimo, obtenemos una parcialmente un cdigo errneo. Es errnea en el


sentido de que cualquier referencia absoluta a una etiqueta o cualquier uso de smbolos
externos lleva a cdigo falso- palabras. Como ser corregida por el vinculador, es
necesario que el ensamblador para proporcionar el vinculador con informacin til. El
ensamblador se comunica esta informacin con una tabla de reubicacin, donde la
lista de instrucciones para corregir se indic, como son las reglas a aplicar para hacer
las correcciones. No vamos a entrar en cmo funcionan las tablas de reubicacin, en
parte porque la informacin completa sobre su funcionamiento no est disponible
pero en parte porque el desarrollador no tiene acceso directo y, por consiguiente, es
imposible modificar su contenido. An es interesante, sin embargo, al menos por
curiosidad, para ver el contenido de una de estas mesas: Ejemplo 9.5 ofrece la tercera
seccin ELF del principal.o archivo. Esta seccin corresponde a la tabla de
reubicacin de la seccin Cdigo mycode del correspondiente archivo de origen.

Podemos ver que para esta pequea seccin de cdigo, el enlazador tendr cinco
traslados a llevar a cabo. Cada uno de estos traslados se caracteriza por su
desplazamiento (segunda columna). La reubicacin puede venir completamente
desde el exterior (Ref indicada en la ltima columna) o de manera relativa, con
respecto a otra seccin del mdulo actual (el nombre de la seccin donde el dato
relativo se encuentra aparece en la ltima columna).
188 Assembly Language Programming
From Listing to Executable: External Modularity 188

EJEMPLO 9.5.- Extracto de un archivo ELF: la tabla de reubicacin

** La seccin #3 '.relmycode' (hojas_REL)


Tamao : 40 bytes (4) Smbolo
de alineacin mesa #6 '.symtab'
5 reubicaciones aplicado a la seccin #2 "MICDIGO"

# Offset Tipo de Wrt Smbolo Definido en


reubicacin
0 0x00000008 10 R_ARM_THM_CALL 12 ReadData Ref
1 0x00000008 10 R_ARM_THM_CALL 12 ReadData Ref
2 0x0000000C 10 R_ARM_THM_CALL 13 Ave_Weight Ref
3 0x00000014 2 R_ARM_ABS32 8 Val1 #1 'mydata'
4 0x000000018 2 R_ARM_ABS32 9 Val2 #1 'mydata'

9.3. El papel del


vinculador

El vinculador completa la creacin de un programa que rene a los diferentes


mdulos en un nico archivo llamado un ejecutable.

9.3.1. Principio de
funcionamiento

Cuando llamamos al enlazador (tambin llamado editor de enlaces), le damos una


lista de mdulos para reunir que contienen cada una de una serie de secciones de
entrada. El vinculador es tambin informado de la disposicin de la memoria de el
destino en el que se ejecutar el programa. Este diseo est codificada en el archivo
project.sct. El trabajo a realizar es relativamente simple: las diferentes secciones de
entrada se agrupan a fin de darles direcciones compatibles con la distribucin de la
memoria.

En nuestro ejemplo, al invalidar las opciones que permiten la inclusin de


informacin de depuracin, el CallProc.o archivo contiene 16 secciones diferentes, y
el principal.o archivo contiene 11 de ellos. Luego nos indican que hay 128 KB de
memoria de slo lectura (ROM) en la direccin 0x08000000 y 20 KB de memoria
de acceso aleatorio (RAM) en la direccin 0x20000000.

REMARK 9.3.- La distribucin de memoria usada aqu es la de un STM32103RB, que


es el controlador del destino para este proyecto. La falta de direcciones de memoria
para el menor , debe tenerse en cuenta que esto es contrario a que se impusiera la
localizacin de la tabla de vectores de interrupcin (ver ejemplo 8.1). Esta
contradiccin es slo aparente porque STMicro ha decidido introducir un alias entre
el [0x00000000 a 0x07FFFFFF] zona
189 Assembly Language Programming
From Listing to Executable: External Modularity 189

Y otra zona como una funcin del estado de dos pasadores, despus de un reinicio. El
principio de esta maniobra es ser capaz de encontrar el vector de reset (y por lo tanto
el cdigo de reinicio) en la memoria Flash interna, en la memoria del sistema o en el
interior de RAM esttica. Aqu la zona de destino del alias es [0x08000000 a
0x10000000], que corresponde a la memoria Flash interna. En este proyecto, las
direcciones bajas estn presentes, incluso si son virtuales.

Recordemos que la arquitectura Cortex-M3 es del tipo Harvard, por lo que hay una
separacin completa del cdigo y los datos de las zonas (vase la figura 1.5). El
vinculador debe, por lo tanto, asignar las secciones de cdigo con direcciones
presentes en el [0x00000000-
0x1FFFFFFF] zona y las secciones de datos con direcciones presentes en el
[0x20000000-0x2FFFFFFF] zona.

Cada seccin de entrada recibidos por el vinculador tiene un tipo y atributos. Los
tres tipos principales son:
- RO () Zona de slo lectura, la cual es una ROM o Flash zona cuyo contenido
tpico es el cdigo. Es comn (en el mundo GNU, por ejemplo) para ver la
abreviatura .texto para este tipo de seccin.
- RW (lectura/escritura) zona, que es una zona de RAM cuyos contenidos tpicos
son los datos inicializados. El sinnimo habitual para esto es .datos;
- ZI () Zona Cero inicializado. Esta es tambin una zona de lectura y escritura que
contendr datos no inicializados. Por defecto ZI zonas estn a 0. Este tipo de seccin
es tambin llamado
.BSS
.

Adems de escribir, hay toda una serie de atributos que, en el caso de aquellos que
se encuentran a la cabeza de Elf archivos, permiten la grabacin de diferentes
informaciones que puedan ser requeridos por el vinculador, carga o incluso la
depuracin simblica.

En un primer simplistas (pero no completamente falsa) la visin, la labor del


vinculador, por lo tanto, consiste en recuperar la lista y el tamao del conjunto de
datos y cdigo de secciones, reunirlos y distribuirlos en las zonas de memoria
correspondiente. Concatena los diferentes pedazos por combinar adecuadamente las
tablas de smbolos: es suficiente para corregir los valores de las etiquetas de los
mdulos aadidos sucesivamente por incrementar progresivamente el tamao de las
secciones. Por ltimo, el vinculador cambia la direccin inicial de cada seccin,
determinando su direccin definitiva. Una vez ms, se lleva a cabo la correccin de
las instrucciones mediante la reubicacin de tablas. Esta visin simplista no es
suficiente: en realidad el producto de el enlazador no puede ser llamado
correctamente un archivo ejecutable. Se produce una imagen de un archivo ejecutable
que ser "visto" de manera diferente en el nivel de carga o en el plano de la ejecucin
propiamente dicha.
190 Assembly Language Programming
From Listing to Executable: External Modularity 190

9.3.2. Los productos del vinculador

9.3.2.1. El archivo de mapa


Uno de los archivos generados es un archivo informa de la asignacin de memoria
elegido (Project.mapa). Al igual que con los archivos .lst, no tiene ningn uso en el
resto del proceso (carga, ejecucin y depuracin simblica) pero es rico en
informacin para los curiosos programador. Este archivo contiene la lista de todos los
smbolos encontrados durante la creacin del archivo ejecutable con los valores
numricos que han sido asociados con, su tamao, su seccin de origen, etc. Un
extracto de esta tabla est dada en el Ejemplo 9.6. Podemos deducir de este extracto
que un cierto nmero de smbolos que aparecen en la tabla que especficamente no se
utilizan en los anuncios. No olvidemos que, de forma ms o menos explcita, el
ensamblador utiliza bibliotecas. Recursos.lib es una librera que se incluye
explcitamente en el proyecto. El brazo-Keil development suite tambin incluye
la librera MicroLib, cuya funcin es suministrar, por ejemplo, las rutinas de
inicializacin. Todas estas inclusiones aportan su cuota de smbolos que encontramos
en el archivo .map . Tambin podemos comprobar que la seccin Direcciones o
etiquetas de cdigo han sido resueltos y que sus direcciones se encuentran ahora en
una direccin en la asignacin de cdigos de zona. El Ave_Weight , procedimiento que
en la tabla de reubicacin para esta seccin en el ejemplo 9.5 tiene un valor de
0x0000000C, y ahora est resuelto en la direccin fsica
0x0800017D.

EJEMPLO 9.6.- Extracto del informe de mapa principal.Archivo de vinculador

Nombre de Valor Tipo Tama Objeto(Seccin)


smbolo o
Restable 0x08000000 Secci 236 Stm32f10x.o(RESET) entrada.o(.a
cer
0x080000C n 0 rm.Recoger$000000) entrada2.o
.ARM.Recoger$00000 E
Secci 4 (.arm.Recoger$000001)
0
0x080000C
n 4 entrada5.o(.arm.Recoger$00000
.ARM.Recoger$00000 E
1 Secci 8 4)
0x080000f0
.ARM.Recoger$00000 n 4 entrada7.o(.arm.Recoger$00000
0x080000f4
4
Secci 4 7)
0x080000F
.ARM.Recoger$00000
C n 28 entrada2.o(.arm.Recoger$00271
7
0x080000F Secci 36 2)
.ARM.Recoger$00271
C n entrada2.o(.arm.Recoger$00271
2 14
0x08000100
Encend Secci 2 2) stm32f10x.o(.text) init.o(.
ido 0x0800011c n Secci text)
14
000000
0x08000140 n de Handlers.o(i. scatterload_cp)
28
.text
0x0800014e datos handlers.o(i.
56
.text
0x08000150 Secci 12 scatterload_handlers.nul o(i.
I.
0x08000160 n scatterload_zi)
2
scatterload
0x0800017c Secci test.o(mycode)
2
_cp i.
0x20000000 n callproc.o(mycode)
512
scatterload
0x2000000c Secci test.o(mydata)
_nul i.
0x2000000c n callproc.o(mydata)
scatterload
0x20000010 Secci callproc.o(mydata)
_zi
n stm32f10x.o(Pila)
Mycode
Secci
Mycode
n
Mydat
Secci
a
n
Mydata
Secci
Coef
n
Pila
191 Assembly Language Programming
From Listing to Executable: External Modularity 191

Princi 0x08000161 ThumbCode 18 Test.o(mycode)


pales
Ave_Weight 0x0800017d ThumbCode 38 Callproc.o(mycode)
ReadData 0x080001a3 ThumbCode 2 Callproc.o(mycode)
Val1 0x20000000 Datos 2 Test.o(mydata)
Val2 0x20000002 Datos 2 Test.o(mydata)
Resu 0x20000004 Datos 8 Test.o(mydata)
Initial_sp 0x20000210 Datos 0 Stm32f10x.o(Pila)

9.3.2.2. La imagen de archivo ejecutable


El archivo utilizado posterior es la imagen de un ejecutable. No es un archivo
ejecutable, en la medida en que deben transferirse a la memoria del procesador antes
de poder iniciar su ejecucin. A fin de realizar esta transferencia posible y eficaz, el
brazo- Keil gama evolucin una vez ms utiliza un elfo de codificar y almacenar los
resultados de este trabajo.

Antes de detallar la composicin de este archivo, primero vamos a observar la


informacin devuelta por el toolchain. Esta preocupacin por el tamao relativo de
las distintas secciones que componen el archivo ejecutable. Para el proyecto se
presenta en este captulo, aqu est el informe:

El tamao del programa: Cdigo = 200 RO-data = 268 RW-data = 12 ZI-data = 516

- el cdigo zona toma 200 bytes. A priori, no hay nada que decir acerca de esto.
Nuestros dos "fuente" archivos contienen slo 22 lneas de instrucciones (seis
para Principal.s y 16 para CallProc.s). Esto genera entre 44 (codificacin slo en el
pulgar) y 88 (codificacin slo en pulgar2) bytes de cdigo, pero el proyecto no se
limita a eso. El cdigo tambin se compone de otros archivos
(STM32F10x.s y resource.lib) y el MicroLib;
- rw- zona de datos tarda 12 bytes. Las listas muestran slo cuatro declaraciones
de variables, la contabilidad de 10 bytes (dos para Coef, dos para val1, dos para Val2 y
cuatro para Resu). Los dos bytes extra son falsos bytes que se agreg debido a que la
secuencia de inicializacin funciona con Word transferencias (y hasta cuatro bytes):
12 bytes correspondientes a tres escrituras. Sin embargo, estn reservadas por el
vinculador para evitar la inicializacin causando modificacin de zonas de memoria
no deseados;
- la Zi-data toma 516 bytes: en nuestro proyecto, estos datos no inicializados estn
relacionadas con la pila del sistema. Esto es creada en el STM32F10x.s archivo (ver
Apndice C), que tiene un tamao de 512 bytes. El extra de cuatro bytes son debido a
la alineacin. En la declaracin de la seccin de opciones que aloja la pila,
encontramos la opcin Align = 3. Esto implica que la direccin de reserva de la pila
debe comenzar en un triplemente siquiera abordar (termina en 3 bits en 0). Si nos
fijamos en la asignacin de memoria en la Figura 9.6, la ltima variable es Coef
almacenado en la direccin 0x2000000C. El primero gratis triplemente incluso
192 Assembly Language Programming
From Listing to Executable: External Modularity 192

Direccin es la direccin 0x20000010; esto corresponde a la direccin de la pila


(STACK). Los tres bytes son "perdido", sin embargo, se cuentan en el nmero total de
bytes en la Zi- zona de datos;
- queda una zona de datos colocados en la ROM: RO-data. Este tipo de zona no
aparecen claramente en la lista de secciones de entrada. Despus de todo, lgicamente
parece bastante paradjica para declarar variables que tienen acceso RO. Estas zonas
no corresponden a zonas de piscina Literal (vase la seccin 4.2.2.3), que si bien son
un valor inmediato zonas son parte integrante del cdigo y se contabilizan como tales.
De hecho, este pasaje de datos corresponde a las 59 entradas en la tabla de vectores de
interrupcin (236 bytes). Para hacer el ltimo 268 bytes, agrega 12 bytes que
componen una tabla denominada regin Tabla$$$$. en el brazo en el contexto. Esta
tabla funciona como vamos a describir un poco ms tarde para (re)inicializar el RW-
datos o para restablecer la Zi-datos justo despus de un reinicio.

La diseccin se nos muestra, en el plano de la ejecucin, que un programa simple


se compone de cuatro elementos de la memoria. La principal labor del linker es, por
lo tanto, imponer una asignacin de memoria para las distintas regiones (vase la
figura 9.3), de acuerdo con el objetivo declarado de la memoria.

El archivo resultante es por lo tanto un conjunto de secciones (ahora


llamado output secciones) que se agrupan en zonas de memoria completamente
determinado. El archivo ELF contiene estos archivos, que en el caso descrito para las
secciones de entrada tienen atributos y propiedades. La primera de estas secciones se
tiene el atributo ER_IROM1, ER, que significa regin de ejecucin. Esta regin
contiene las tablas de vectores de interrupcin, todo el cdigo y la regin$$$$
Tabla Tabla. La siguiente seccin es el RW-datos que contenga todos los datos
inicializados, entonces la seccin describiendo la Zi-datos. Estas secciones le
permiten al sistema de desarrollo para producir datos que ser concretamente cargado
en memoria. Estos datos se presentan como una lista de direcciones de memoria,
seguido por el contenido con el que deben ser asignados. La funcin de la cargadora
es para llevar a cabo este escrito. Estas direcciones son, sin embargo, slo las zonas
de cdigo (y, por tanto, corresponden a valores congelados durante la ejecucin). Por
definicin, esto excluye RW-datos y ZI-data. La imagen del ejecutable se compone
de cdigo, RO-datos y una copia de rw-datos colocados justo despus de
la regin$$$$ Tabla Tabla. Por lo tanto, hay un transporte de rw-datos a una zona de
memoria permanente, lo cual deja la posibilidad de reinicializar todas las variables de
programa tras cada reinicio.

Permtanos volver y completar lo que sucede despus de


un restablecimiento (vase la seccin 8.1). El procesador, una vez inicializado, se
ejecuta la rutina se presenta en el Apndice C. Este procedimiento termina con un salto
a la etiqueta principal. Esta etiqueta es el punto de entrada de una rutina que
implementar la inicializacin de rw-datos y (restableciendo las direcciones de
memoria correspondiente) la creacin de la Zi-data. Esta informacin se lee en
la regin$$$$ table tabla que contiene las direcciones de inicio de variables y los de
su copia en memoria permanente, como el nmero de palabras que se van a copiar.
Ella
193 Assembly Language Programming
From Listing to Executable: External Modularity 193

Tambin contiene las direcciones de zonas no inicializada (que se borrar al ser reset)
y el nmero de palabras que contienen. Esta tabla es un elemento esencial para
la librera MicroLib y tambin para la aplicacin integrada que permite que el
destino sea reiniciado completamente en determinadas condiciones.

0x20005000

Inicializacin Datos ZI
0
0x20000010
RW Data
0x20000000
Inicializacin
en la pila de
de los datos

0x10000000

datos (valores Datos RO


0x080001D4
iniciales)
Regin$$$$Tabla
Cdigo RO
Cdig
ejecuci
Regin

0x080000CE
n
de

o
T.V.I Datos RO
0x08000000
Base

Datos (valores
iniciales)
Regin$$$$Base mesa
Cdig
o
T.V.I
0x00000000

La figura 9.3. La asignacin de las distintas regiones de un proyecto

REMARK 9.4.- El programa principal, como en el caso de C, debe contener un


procedimiento principal que corresponde al punto de entrada del programa de usuario.
Esta etiqueta se declara pblicamente para ser visible en el exterior la secuencia de
inicializacin. El procedimiento de arranque termina con una llamada a la referencia,
que es el principal punto de entrada de la biblioteca MicroLib. Una vez que su
trabajo ha sido llevado a cabo, esta biblioteca pide el usuario interno por una rama de
la etiqueta principal.

9.3.2.3. La "dispersin" de
carga_file
Como acabamos de ver, el enlazador necesita una descripcin de la distribucin de
memoria para saber dnde asignar las diferentes secciones que componen su archivo
ejecutable. En la herramienta de cadena de Keil , Visin es una interfaz que nos
permite introducir las direcciones donde los diferentes bloques de memoria estn
ubicados. Por defecto, una vez dado el controlador del destino, el equipamiento de
las direcciones de memoria del chip (on
194 Assembly Language Programming
From Listing to Executable: External Modularity 194

La memoria chip) estn llenos. Si hay otros dispositivos de memoria presente en el


destino, es necesario proporcionar a sus especificaciones, incluida la asignacin de la
memoria. Sin embargo, el vinculador no utilizar directamente los datos de interfaz ,
pero la dispersin_cargar el archivo que se genera automticamente por la interfaz.
Este archivo es un archivo de texto que describe la distribucin de memoria
formalmente y con su propia sintaxis. Un usuario avanzado puede perfectamente editar
y modificar este archivo y omitir la interfaz para informar directamente al vinculador.
Este archivo est dividido en tres regiones distintas:
- carga de regiones: estas son las zonas de memoria donde el cdigo y RO-datos se
transferirn a la memoria. Pueden ser mltiples, aunque como en el caso del ejemplo
de un simple ejecutable, una sola regin es suficiente para albergar todos los datos
que se transfieren.
- ejecucin de las regiones: estas son las regiones en donde se almacenar el cdigo;
- lectura y escritura (rw) accesible regiones: estas son las regiones donde las
variables de programa ser almacenado.

Para el presente ejemplo, el archivo de carga_Scatter pueden recomponer las lneas


Ejemplo 9.7.

EJEMPLO 9.7.- El ejemplo de un archivo de descripcin de la


memoria: un caso simple

LR_IROM1 0x08000000 0x00020000 { ;


ER_IROM1 0x08000000 0x00020000 { ;
.Cualquier (+RO
) ;
}
RW_IRAM1 0x20000000 0x00005000 { ;
.Cualquier (+RW +ZI) ;
}
}

Permtanos descifrar estas pocas lneas:


- lnea delimita la regin de carga: el vinculador debe generar un archivo ELF para
que la lista de direcciones en las que el cargador har las transferencias
estarn comprendidos entre 0x08000000 y 0x08020000. Esta regin abarca (la
presencia de los caracteres { y } encapsula la declaracin) de todas las regiones
correspondientes a las diferentes entidades de la imagen ejecutable;
- lnea indica donde la direccin interna de la memoria ROM se encuentra en la
regin de ejecucin. En nuestro caso implica el flash interno de STM32, que corresponde
a
128 KB a partir de la direccin 0x08000000. Cabe sealar que esto corresponde
195 Assembly Language Programming
From Listing to Executable: External Modularity 195

Exactamente a la regin de Carga de direcciones, y es absolutamente normal, ya que


el cdigo ser escrito en su colocacin definitiva.
- lnea Especifica que el vinculador que todos RO secciones de entrada debe
colocarse en esta regin de ejecucin;
- lnea Delimita el RW accesible regin. Reconoce los 20 KB de esttica
RAM disponible dentro del STM32 desde la direccin
0x20000000.
- lnea Nos permite indicar al vinculador que debe poner todos los inicializado
(rw) o (ZI) las variables no inicializadas en esta
regin.

Para cada regin de ejecucin incluido en la zona de carga, es posible especificar


qu partes del cdigo y los datos deben ser incluidos. Esto slo tiene sentido cuando
hay varias zonas de carga y hemos especificado la distribucin entre las distintas
zonas. Clsicamente, cada una de estas regiones corresponden a diferentes zonas de
memoria. De hecho, por consiguiente, una aplicacin incrustada en un objetivo real,
de hecho es comn que los dispositivos de memoria que acaba de completar la
memoria que ya
Existe dentro de
la controlador.

Como un ejemplo, imaginemos que ejecuta el ejemplo en un destino diferente


utilizando dos zonas de ROM (16 KB en la direccin 0x00000000 y 4 KB de la
direccin
0x00500000), as como dos zonas de RAM (4 KB en la direccin 0x20000000 y 1
KB de la direccin 0x20030000). La Dispersin_Cargando archivo correspondera
a Ejemplo 9.8.

EJEMPLO 9.8.- Un archivo de descripcin de la memoria: un caso con varias


regiones de carga

Cargar_ROM_1 0x00000000 0x00004000 {


EXEC_ROM_1 0x00000000 0x00004000 {
Principal.o
(+RO)
.Cualquier (+r
o)
}
Ext_RAM 0x20000000 0x00001000 {
Principal.o
(+RW+ZI)
.Cualquier (+
ZI)
}
}
Cargar_ROM_2 0x00500000 0x00001000 {
EXEC_ROM_2 0x00500000 0x00001000 {
AppleProc.o (+RO)
}
196 Assembly Language Programming
From Listing to Executable: External Modularity 196

SRAM 0x20030000 0x00000400 {


AppleProc.o (+RW+ZI)
.Cualquier (+R
W)
}
}

Esta segunda distribucin de memoria no es muy realista, pero nos permite ver
cmo es posible imponer sobre el vinculador de una distribucin de los distintos
mdulos en las cuatro zonas de memoria. El RO del cdigo y los datos de
la principal.o mdulo tendr que ser asignado en la primera regin de ejecucin que
incluye la ROM EXEC_ROM_1 y EXT_RAM. La segunda regin de
carga (LOAD_ROM_2) recibir todas las secciones de la CallProc.o mdulo. Tambin
se especifica que el resto de RO datos sern asignados a EXEC_ROM_1 regin, que
sern datos no inicializados en el ext_RAM regin y que el resto de los datos
inicializados se colocarn en la regin de SRAM.

REMARK 9.5.- En un controlador de , la memoria es de un tamao reducido. Durante


la ejecucin, con frecuencia es til tener la opcin de reutilizar las zonas de memoria
que contenga los datos cuando stos se vuelven intiles para el resto de la ejecucin
(datos obsoletos). Esta prctica se llama superposicin. El lenguaje ensamblador
ofrece la opcin de superposicin de varias secciones de datos en el mismo intervalo
de memoria utilizando el sentido comn (vase la seccin 3.5.1).

En el caso de desarrollo con las herramientas GNU Free, el protocolo utilizado es


diferente. El vinculador utiliza un archivo para recuperar la informacin sobre la
distribucin de la memoria del destino, as como las normas de atribucin y arbitraje
de esta memoria para las distintas entidades en el programa. El formalismo, no descrito
aqu, es el tipo de descriptor de vinculador, cuya extensin estndar es *.ld. Cuando
usamos este tipo de herramienta (vase, por ejemplo, [COD]), es posible descargar los
archivos de ejemplo y cuya modificacin es posible si el lector ha comprendido
los principios presentados aqu.

9.4. El cargador y la unidad de


depuracin

En un ordenador, tenemos suficientes recursos para construir un programa


diseado para ejecutarse en la misma mquina, o cualquier mquina similar equipado
con el mismo procesador y el mismo sistema operativo; lo llamamos desarrollo
nativo. Este no es el caso en un
controlador. Tambin requiere otro equipo - el host - para construir el software
Desarrollado para el destino controlador: esto se llama desarrollo transversal. Una
vez que la
Software se ha creado, puede ser colocado en la ROM (por derribar una memoria de
slo lectura programable borrable (EPROM), que implantamos en la tarjeta
197 Assembly Language Programming
From Listing to Executable: External Modularity 197

Que contiene el controlador de , pero este enfoque es muy incmodo en la fase de


pruebas de software. Preferimos enviarlo desde el host a la controlador a travs de
un conexin especializada para que el host coloca la imagen del propio ejecutable en
la memoria flash o RAM. Esto ya no es una carga, sino una descarga.

"cargador", el programa se encarga de copiar correctamente las distintas secciones


del programa se coloca en el archivo que contiene la imagen ejecutable en la memoria
y luego, si procede, el lanzamiento de la ejecucin. Esta utilidad se incluye en la
mayora de los cross-suites de desarrollo (como toolchain).

La actual generacin de herramientas utiliza principalmente el JTAG (Joint Test


Action Group) estndar de puerto para descargar los programas directamente a la
memoria Flash. JTAG es un estndar de bus serie sncrona. La depuracin de JTAG
adaptador utiliza este protocolo para comunicarse con el ncleo del procesador. En un
ordenador normal este bus no est presente; el adaptador se comunica luego en
el PC con una conexin clsica (normalmente un Bus Serie Universal [USB]).

El programa de desarrollo o depurador es particularmente til para la bsqueda de


errores en un programa. El programa que se examina se ejecuta bajo el control del
programa de depurador. Para ello, el depurador obedece a las rdenes que el usuario
le ha dado en lnea. Esto puede iniciar la ejecucin del programa en modo continuo o
paso-por-paso mode: en este ltimo caso, slo una sola instruccin del programa se
ejecuta y el depurador toma de nuevo el control. El usuario puede colocar un punto de
interrupcin en una instruccin del programa que se examina antes de iniciar la
ejecucin del programa: esto interrumpir la ejecucin justo antes de esta instruccin.
En cada parada en el programa, el depurador proporciona el contenido actual de todos
los registros del procesador y, a continuacin, el usuario puede averiguar el estado
actual del programa; l/ella tambin puede buscar en el contenido de la pila del
sistema o cualquier otra regin de memoria. Por lo tanto, l/ella puede conocer el valor
actual de un dato para que l/ella conoce la direccin (gracias a la tabla de smbolos
dada por el enlazador), o para que l/ella da el nombre si el depurador es simblica.
Cada vez que el programa se detiene, el depurador tambin nos permite cambiar el
valor contenido en cualquier registro o cambiar cualquier variable o posicin de
memoria, antes de reanudar la ejecucin.

Tenga en cuenta que para hacer su trabajo, un depurador simblico al menos


debe tener la tabla de smbolos. De hecho, todos los depuradores necesitan una gama
de informacin que debe incluirse en el archivo ejecutable. Para ello, el programador
debe indicar (invocando el ensamblador y enlazador con opciones especficas) que
deben incluir toda la informacin necesaria para el desarrollo en el depurador.

Como fue presentado en el captulo 1 sobre la corteza de arquitectura (vase la


seccin 1.2.1.2), existen varias unidades de hardware cuyas funciones consisten
principalmente de devolver informacin a un sistema de host sin tener ningn efecto
sobre el funcionamiento del programa siendo
198 Assembly Language Programming
From Listing to Executable: External Modularity 198

Ejecutado. Esto se puede lograr generalmente con el Trace Macrocell unidades que
pueden, en tiempo real y sin causar cualquier alteracin del procesador, analizar y
transmitir datos sobre el comportamiento y el rendimiento de la meta lo observado.
Este enfoque, conocido como no intrusiva en el brazo documentacin, es
particularmente interesante para el sistema de vigilancia, o en el caso de la disfuncin
que es particularmente difcil de localizar o explicar.

En un clsico del ciclo de desarrollo, los primeros pasos de desarrollo requieren


un enfoque mucho ms intrusiva, como poner un punto de interrupcin en una
determinada direccin de cdigo para detener la secuencia durante la ejecucin,
analizando el estado del procesador en ese preciso momento y, a continuacin,
posiblemente reanudar la ejecucin paso a paso.

Arquitectura Cortex-M3 ofrece dos versiones de estas tcnicas intrusivas:


- la primera tcnica consiste en congelar el ncleo del procesador a nivel de
software. Cortex-M3, luego pasa a un estado de depuracin llamada estado interno,
en la cual es posible especificar el paso por paso el funcionamiento del programa que
est siendo ejecutado, entre otras cosas. El sistema de desarrollo, a travs del puerto
JTAG, actos (por RW) directamente en los registros de las unidades de depuracin y
permite controlar desde fuera del programa que se est ejecutando.
- el segundo enfoque, menos intrusivo, consiste en el uso de un Monitor de
depuracin, que es una aplicacin de software incrustado en Cortex-M3 que se activa
mediante una excepcin (vase la seccin 8.2.1.6). La excepcin entonces toma el
control de la ejecucin de la secuencia ejecutado por el procesador y se comunica con
la unidad de desarrollo.
Los objetivos de este libro no incluyen un conocimiento profundo y detallado de
todos los aspectos de la Cortex-M3, no vamos a explicar ms detalladamente los
mtodos y arquitecturas internos implicados en la depuracin. No obstante, es cierto
que la "programacin" de nivel inferior no puede hacerse sin estas herramientas de
desarrollo, aunque slo sea porque el programador no tiene otra forma de observar lo
que sucede en el destino.
UnPPENDICES
Apndice A

La instruccin Set - Lista


alfabtica

La lista de las instrucciones dadas a continuacin no es exhaustiva y est limitado


a las instrucciones comunes y clsico. Cada instruccin se da con las diferentes
frmulas posibles de operandos.

Un

ADC{S}<c> {<Rd>} <Rn> # <const.> Rd rn + const.

ADC{S}<c> {<Rd>} <Rn> <Rm> {<Mays>} Rd Rn


+Mays(RM)
Aadir{S}<c> {<Rd>} <Rn>#<const.> Rd rn + const.

Aadir{S}<c> {<Rd>} <Rn> <Rm> {<Mays>} Rd rn + shift(RM)

Aadir{S}<c> {<Rd>} SP, #<const.> Rd SP + const.

Aadir{S}<c> {<Rd>} SP, <Rm>{<Mays>} Rd SP + shift(RM)

ADR<c> <Rd> <label> Rd direccin de


etiqueta
Y{S}<c> {<Rd>} <Rn> # <const.> Rd Rn y const.

Y{S}<c> {<Rd>} <Rn> <Rm> {<Mays>} Rn Rn y shift(RM)

ASR{S}<c> <Rd> <Rm><im5, #> Rd Rm >>im5

ASR{S}<c> <Rd> <Rn> <Rm> Rd Rn >>rm


202 Assembly Language Programming Appendix A 202

B<c> <label> ETIQUETA DE PC


BFC<c> <Rd> #<LSB> #<Nb> Rd[lsb+Nb-1 : lsb] 0
BFI<c> <Rd><Rn> #<LSB> #<Nb> Rd[lsb+Nb-1 : lsb] Rn[Nota:
BIC{S}<c> {<Rd>} <Rn> # <const.> 0] Rd Rn Y NO(const)
BIC{S}<c> {<Rd>} <Rn> <Rm>
Rd Rn Y NO(shift(Rm))
{<Mays>}
LR volver
BL<c> <label>
etiqueta @ PC
LR volver
BLX<c> <Rm>
@ PC RM
BX<c> <Rm> PC R

CBNZ<c> <Rm> <label> PC etiqueta si (Rm 0)


CBZ<c> <Rm> <label> PC etiqueta si (Rm = 0)
CLZ<c> <Rd> <Rm> Rd CLZ(Rn)
CMN<c> <Rn> # <const.> Banderas test(rn + const)
CMN<c> <Rn> <Rm>{<Mays>} Banderas test(rn + shift(Rm))
CMP<c> <Rn> # <const.> Banderas test(Rn - const )
CMP<c> <Rn> <Rm>{<Mays>} Banderas test(Rn - cambio(Rm))

EOR{S}<c> {<Rd>} <Rn> # <const.> Rd Rn XOR const.


EOR{S}<c> {<Rd>} <Rn> <Rm> {<Mays>} Rd Rn XOR shift(RM)

Yo

Se{x{S}}}{z <firstcond> soluciona la ejecucin de la siguiente instruccin bloquear


203 Assembly Language Programming Appendix A 203

Rk M32 (Rn + 4(k - i)


La LDM<c> <Rk>{Ri-Rj }
Con k = i...j
Rk M32 (Rn + 4(k - i)
La LDM<c> <Rk> !{Ri -Rj } Con k = i...j
Entonces Rn rn + 4 * (j
- i)
Rk
LDMDB<c> <Rk>{Ri-Rj } M32 (Rn - 4(k - i + 1))
Con k = i...j
Rk
M32 (Rn - 4(k - i + 1))
LDMDB<c> <Rk> !{Ri-Rj }
Con k = i...j
Entonces Rn Rn -j - 4 *
(i)
LDR<c> <tr> [<Rn> { #<imm>}] Rt M32 (Rn imm)
Rn rn + imm
LDR<c> <tr> [<Rn> #<imm>] !
luego
Rt M32 (Rn)
RtM32 (Rn)
LDR<c> <tr> [<Rn>] #<imm>
Entonces Rn rn +
imm
LDR<c> <tr> <label> etiqueta
Rt
LDR<c> <tr> [PC, #<imm>] Rt M32 (Pc imm)
LDR<c> <tr> [<Rn> <Rm>{,LSL,#<Mays>}] Rt M32 (Rn + shift(Rm))
Rt M32 (literal)
LDRD<c> <tr> <Rt2>, <Literal>
Rt2 M32 (literal + 4)
Rt M32 (PC + imm)
LDRD<c> <tr> <Rt2>, [PC, #<imm>]
Rt2 M32 (PC + imm + 4)
Rt M32 (Rn + imm)
LDRD<c> <TR><Rt2>[<Rn>{#<imm>}]
Rt2 M32 (Rn + imm + 4)
Rn rn + imm
LDRD<c> <TR><Rt2>[<Rn>#<imm>] ! luego Rt M32 (Rn +
imm)
Y Rt2 M32 (Rn + imm + 4)
204 Assembly Language Programming Appendix A 204

Rt M32 (Rn + imm)


LDRD<c> <TR><Rt2>[<Rn>]#<imm> Rt2 M32 (Rn + imm + 4)
entonces Rn rn + imm
LSL{S}<c> <Rd> <Rm><im5, #> Rd Rm << im5
LSL{S}<c> <Rd> <Rn> <Rm> Rd Rn << RM
LSR{S}<c> <Rd> <Rm><im5, #> Rd Rm >> im5
LSR{S}<c> <Rd> <Rn> <Rm> Rd Rn >> rm

MOV{S}<c> <Rd> # <const.> Rd const.


MOV{S}<c> <Rd> <Rm> Rd RM
MOVT<c> <Rd> #<imm16> Rd[16 : 31] imm16
MSR<c> <Rn><spec_reg> Rn spec_reg
MSR<c> <SPEC_reg><Rn> Spec_reg Rn
MUL{S}<c> {<Rd>} <Rn> <Rm> Rd Rn * RM
MVN{S}<c> <Rd> # <const.> Rd no (const)
MVN{S}<c> <Rd> <Rm> { <Mays>} Rd NO(Mayus (Rn)

NOP<c> No hacer nada


NEG<c> {<Rd>} <Rm> Rd -RM

Oh

Rd RM
El ORN{S}<c> {<Rd>} <Rn> # <const.>
O NO(const)
Rd RM
El ORN{S}<c> {<Rd>} <Rn> <Rm>
O NO(shift(Rm))
{<cambio ORR>}{S}<c> {<Rd>} <Rn> # Rd Rm o const.
Rd Rm o shift(RM)
<const.>
ORR{S}<c> {<Rd>} <Rn> <Rm> {<Mays>}
205 Assembly Language Programming Appendix A 205

POP<c> {Ri-Rj} rk M32 (SP + 4*(k-i)) con k=i...j


Luego SP SP + 4 * (j - i)
Empujar<c> {Ri-Rj} M32( SP - 4*(k-i+1)Rk con k=i...j
Luego SP SP - 4 *(j - i)

RBIT<c> <Rd> <Rm> Rd[31-k] Rm[k] con k = 0... 31


REV<c> <Rd> <Rm> Rd[31 : 24] Rm[7 : 0]
Rd[23 : 16] Rm[15 : 8]
Rd[15 : 8] Rm[23 : 16]
Rd[7 : 0] Rm[31 : 24]
REV16<c> <Rd> <Rm> Rd[31 : 24] Rm[23 : 16]
Rd[23 : 16] Rm[31 : 24]
Rd[15 : 8] Rm[7 : 0]
Rd[7 : 0] Rm[15 : 8]
REVSH<c> <Rd> <Rm> Rd[31 : 8]
Firmado promocin (Rm[7] :
0) Rd[7 : 0] Rm[15 :
ROR{S}<c> <Rd> <Rm><im5, #> Rd 8]rotacin(Rm, im5 bits)
ROR{S}<c> <Rd> <Rn> <Rm> Rd rotacin(Rn, Rm bits)
ROR{S}<c> <Rd> <Rn> <Rm> Rd rotacin([Rn,C], Rm bits)

SBFX<c> <Rd> <Rn> #<LSB> #<Nb> Rd[Nb-1 : 0]


Rn[lsb + Nb-1 : lsb]
SMLAL<c> <Rdlsb > Rd, <P F >, <Rn> <Rm> [Rdmsb :Rdlsb] Rn * RM
+ [Rdmsb :Rdlsb]
SMULL<c> <Rdlsb > Rd, <P F >, <Rn> <Rm> [Rdmsb :Rdlsb] Rn * RM
SSAT<c> <Rd><im5,#><Rn>{<Mays>} Si (Rn < 0) Rd
Min(-2(IM5-1),Mayus
(Rn)
Si (Rn >0) Rd
Max(2(IM5-1) - 1,Mayus
(Rn)
206 Assembly Language Programming Appendix A 206

STR<c> <tr> [<Rn> <Rm> {, LSL M32 (Rn +co locar(Rm))


# <Mays>}] Rt
STR<c> <tr> [<Rn> {#<imm>}] M32 (Rn imm)Rt
STR<c> <tr> [<Rn> #<imm>] ! Rn rn + imm
luego M32 (Rn)
STR<c> <tr> [<Rn>] #<imm> Rt M (Rn) Rt
32
entonces Rn rn +
imm
STM<c> <Rn>{Ri-Rj } M32 (Rn + 4(k - i)) Rk
Con k = i...j
STM<c> <Rn> !{Ri-Rj } M32 (Rn + 4(k - i)) RK
Con k = i...j
entonces Rn rn + 4 (j
STMDB<c> <Rn>{Ri-Rj } M32 (Rn -- 4(k
i) - i + 1)Rk
Con k = i...j
STMDB<c> <Rn> !{Ri -Rj } M32 (Rn - 4(k - i + 1) rk
Con k = i...j
Entonces Rn Rn - 4 (j
Std<c> <TR><Rt2>[<Rn>{#<imm>}] -Mi) (Rn + imm) Rt
32
M32 (Rn + imm + 4) Rt2
Std<c> <TR><Rt2>[<Rn>#<imm>] ! Rn rn + imm
luego M32 (Rn + imm)
Rt
Std<c> <TR><Rt2>[<Rn>]#<imm> Y M32 (Rn +M
imm(Rn
+ 4)
+ Rt2
imm)
32
RT M32 (Rn + imm + 4)
Rt2 entonces Rn rn +
imm
SUB{S}<c> >} {<Rd ,<Rn>#<const.> Rd Rn - const.
SUB{S}<c> >} {<Rd ,<Rn> <Rm> Rd
{<Mays>}
SUB{S}<c> >} {<Rd ,SP,#<const.> Rn - Rd
cambio(RM)
SP - const.
SUB{S}<c> >} {<Rd ,SP,<Rm> {<Mays>} Rd
SBFX<c> <Rd> <Rn> #<pf> #<Nb> SP - Rn[
Rd[Nb-1 : 0] cambio(RM)
pf+Nb-1 : pf ]
Rd[31 : Nb] Rd [lsb + Nb - 1]
SXTB<c> <Rd> <Rm> { <rotacin>} Rd32 de rotacin (Rn)[7 : 0]
Rd[31 : 8]
Rd[7].
SXTH<c> <Rd> <Rm> { <rotacin>} Rd32 de rotacin (Rn)[15 : 0]
Rd[31 : 8]
Rd[15].
207 Assembly Language Programming Appendix A 207

TEQ<c> <Rn> # <const.> Banderas test(Rn) const XOR


TEQ<c> <Rn> <Rm>{<Mays>} Banderas test(Rn XOR shift(Rm))
TST<c> <Rn> # <const.> Banderas test(Rn y const)
TST<c> <Rn> <Rm>{<Mays>} Banderas test(Rn y shift(Rm))
TBB<c> [<Rn> <Rm>] PC PC + Rn[ara]
TBH<c> [<Rn> <Rm> LSL #1] PC + Rn[ara]

UBFX<c> <Rd> <Rn> #<LSB> #<Nb> Rd[Nb-1 : 0]


Rn[lsb + Nb - 1 : lsb]
Rd[31 : Nb] 0
UDIV<c> {<Rd>} <Rn> <Rm> Rd Rn RM
UMLAL<c> <Rdlsb > Rd, <P F >, <Rn> <Rm> [Rd Rdlsb msb :] Rn * RM
+ [Rd Rdlsb msb :]
UMUL<c> <Rdlsb > Rd, <P F >, <Rn> <Rm> [Rd Rdlsb msb :] Rn * RM
USAT<c> <Rd><im5,#><Rn>{<Mays>} Rd
Max(2(IM5-1) - 1 , SHIFT(Rn)
UXTB<c> <Rd> <Rm> { <rotacin>} Rd32 de rotacin (Rn)[7 : 0]
Rd[31 : 8] 0
UXTH<c> <Rd> <Rm> { <rotacin>} rotacin Rd32 ((Rn)[15 : 0]
Rd[31 : 8] 0
Apndice B

El temporizador
SysTick

B.1. Contadores y temporizadores


en general

Contadores y temporizadores son dos entidades que debemos encontrar en


un controlador . Ambos hacen exactamente lo mismo. De hecho corresponden a los
registros que contar hacia arriba o hacia abajo y tienen ascendentes o descendentes, o
en ambos frentes. La diferencia entre los dos nombres que, en el caso de
temporizadores, la secuencia frontal que suministra la unidad es peridica y tiene un
plazo conocido (que a menudo es ajustable). Esto implica que el valor contenido en el
registro corresponde a un tiempo de medicin, de ah su nombre.

El principal evento que ocurre en el proceso de incremento o decremento,


respectivamente) es el desbordamiento o subdesbordamiento de la capacidad del
registro. Muchas cosas pueden intervenir en este evento, pero las dos principales
acciones programables de desbordamiento (subdesbordamiento) estn enviando una
solicitud de interrupcin y la recarga de un valor dado en el recuento registro,
causando una muestra llamada a una rutina especfica. Esta funcionalidad es necesaria
para el desarrollo de un kernel en tiempo real cuya funcin principal es compartir una
unidad central de procesamiento (CPU) el tiempo entre las diferentes tareas que se
ejecutan en el procesador. La motivacin para la mquina avanzada de RISC (brazo)
para proporcionar una eleccin
Temporizador dentro del ncleo se vea libre de las especificidades de los controladores
( y as
Ser libres de la eleccin de los desarrolladores) a fin de que la base del kernel en tiempo
real podra ser desarrollada por todos los circuitos basados en Cortex-M3. En su sitio
web, brazo enumera los socios proponer estos kernels en tiempo real consistemas
operativos en tiempo real () - hay ms de 20, y la lista est sujeta a cambios frecuentes.
210 Assembly Language Programming Appendix B 210

Solicitar n15
Valor mximo: 0x00FFFFFF
Valor actual

N
Valor de recarga

Inicio
Ciclo de desbordamiento: (N+1)*h
Clcck

H: perodo de reloj

Figura B.1. Principio de funcionamiento del temporizador SysTick

B.2. SysTick

La SysTick timer es un temporizador de decremento de 24 bits. A diferencia de los


complejos de unidades de temporizador que podemos encontrar en una controlador,
no tiene otros modos de funcionamiento de un
Decremento de 24 bits. Su funcionamiento general se resume en la Figura B.1.

La unidad SysTick se compone de cuatro registros, que sern descritos en un


momento. Tres de estos registros son clsicas: uno para administrar el estado y
configuracin, uno para contener el actual valor de cuenta regresiva, y uno para la
recarga de valor. La cuarta es ms particular y muestra la razn por la que esta unidad.
Se trata de un registro que contiene el valor de dar un valor de recarga estndar con
el fin de dar un 10 milisegundos de interrumpir la periodicidad.

Una sutileza est en cmo evitar errores en la programacin de este temporizador.


La solicitud de interrupcin tiene lugar cuando el valor actual cambia de 1 a 0, pero
la recarga slo se lleva a cabo en el prximo flanco ascendente del reloj. Obviamente,
esto significa que en el caso de funcionamiento peridico (que es a priori el
funcionamiento clsico) la interrupcin llamada tiene una periodicidad de N + 1 ciclos
de reloj, siendo N el valor almacenado en el registro de recarga. En el
ejemplo presentado (ejemplo B.1), este valor de recarga primero se calcul como el
cociente (divisin entera) entre la frecuencia del reloj interno (Freq_Quartz) y la
frecuencia de solicitudes (Freq_Request). Esta proporcin es entonces
211 Assembly Language Programming Appendix B 211

Disminuye en uno para tener en cuenta el intervalo entre la interrupcin y la recarga.


Por ltimo, tenga en cuenta que en dicho clculo la frecuencia de peticin no
necesariamente coincide con la verdadera frecuencia de funcionamiento. De hecho,
como este clculo se basa en una divisin entera, no hay ninguna garanta de que el
resto de esta divisin ser cero. Otro, ms atpica, funcin es posible y consiste en la
modificacin del valor de carga cada vez que el controlador est activado. Por
definicin, ya no se trata de una funcin peridica, sino una funcin de reloj de alarma
cada vez reprogramado, suponemos est calculada para corresponder con N ciclos de
reloj. Como directa "a mano" por la cesin de recarga el valor actual no es posible, se
puede llevar a cabo esta reprogramacin, afectando el valor de recarga, pero con N en
vez de N - 1. De hecho, podramos considerar que el arranque del temporizador
corresponde a la siguiente interrupcin y como la activacin tendr lugar como el
valor actual cambia de 1 a 0, lo normal es que empiece con el valor calculado.

B.3. Los registros SysTick

B.3.1. El actual registro de valor

Cuando SysTick est activo, el valor de este registro disminuye con cada aumento
frente al reloj. Como este temporizador est codificado en 24 bits, los 8 bits ms
significativos en este registro, estn siempre en el 0. Es posible obtener acceso de
lectura para averiguar el valor actual. Sin embargo, si se permite el acceso de
escritura, es limitada: cualquiera que sea el valor que desea escribir, dicho acceso se
traducira en la eliminacin de los contenidos. Por lo tanto, no es posible escribir un
valor a este registro - slo puede borrar uno.

B.3.2. El registro de control y estado

Este registro (vase la Figura B.2) tiene slo cuatro bits significativos:
- COUNTFLAG: cambia a 1 si el recuento registro (Valor Actual) ha cambiado
a 0. Se restablece cuando el procesador lee el registro con este bit decontrol y estado
(), o cuando el procesador escribe un valor en el registro de valor actual. Este bit
permite el uso del temporizador sin utilizar interrupciones, simplemente escaneando
el estado de este bit. Obviamente, esto no es tan eficaz como la interrupcin porque
utiliza el anlisis del tiempo de CPU. Lo que es ms, la deteccin no es simultnea con
el evento, as que la precisin de la medida del tiempo no est garantizada.
- CLKSOURCE: hay dos fuentes de reloj que abastecen el temporizador. La
primera, que es estndar y se corresponde con el bit se establece a 1, consiste
en utilizar el reloj interno del Cortex-M3. No obstante, es posible (con el conjunto de
bits a 0) para especificar
Un reloj externo. Este reloj slo es externo a Cortex-M3 y no el controlador que
integra y debe ser una fraccin (al menos 2,5 veces ms pequea) del interno
212 Assembly Language Programming Appendix B 212

Frecuencia, simplemente porque una mayor frecuencia sera incompatible con la


actualizacin de los valores de registro. Es necesario consultar la documentacin del
circuito utilizado para averiguar la frecuencia de estos dos relojes.

La Figura B.2. Control y registro de estado


SysTick

- TICKINT: cuando est ajustado a 1, permite el lanzamiento de la excepcin


SYSTICK (15 entrada en la tabla de vectores de interrupcin) cuando el decremento
del temporizador le 0.
- Enable: esta es la parte que comienza (bit a 1)/topes (bit a 0) el temporizador. Tan
pronto como este bit est activado, cada aumento frente al reloj elegido provoca el
decremento del actual registro de valor. En el momento en que se cambia a 1,
el actual registro de valor est cargada con el valor contenido en el registro de recarga.

B.3.3. La recarga
registrarse

Este registro, en la medida en que sirve como un valor para restablecer el valor
actual registro, slo puede recibir un valor entre 1 y 0x00FFFFFF. Es posible
asignarle un valor de 0, pero esto impedira el funcionamiento de SysTick. Despus de
un reinicio, el valor de este registro es impredecible.

B.3.4. El valor de calibracin


registrarse

Un tiempo de muestreo de 10 milisegundos parece ser un valor de referencia, de


acuerdo con el brazo, para calibrar la velocidad de un kernel en tiempo real. Este valor
de calibracin registro (vase la Figura B.3) con acceso de slo lectura nos permite
averiguar el valor de recarga para dar
Para obtener este valor de muestreo sin disecar la controller
213 Assembly Language Programming Appendix B 213

La documentacin. El principal dato, TENMS (10 milisegundos) (los 24 bits menos


significativos) es por lo tanto un valor establecido por el diseador del circuito. Si se
desean ms adelante otro periodo de muestreo, proporcional a 10 ms, slo tenemos que
leer este registro, agregar 1 para obtener el nmero de ciclos correspondientes a estos
10 ms, aplicar la necesaria relacin de proporcionalidad (multiplicacin o divisin),
reste 1 y modificar el valor de recarga con este valor.

Dos bits completar esta informacin:


- el peso de 31-bit indica que no hay ninguna seal de reloj externa.
- el peso de 30 bit indica que el valor de 10 ms no es exacto debido a la frecuencia
de reloj de valor. La precisin de un muestreo basado en TENMS no es, por tanto,
garantizada.

La Figura B.3. Calibracin SysTick registrarse

B.4. Ejemplo de programacin


SysTick

En este ejemplo, tres procedimientos genricos han sido escritas. Los dos primeros
(_de_inicio y Stop_SysTick SysTick) nos permiten iniciar/detener el temporizador. La
tercera (SysStickSetPeriod) se llama Start_SysTick para calcular el valor de recarga
necesaria para operar el SysTick periodicidad en un valor elegido
(Freq_Request). Suponemos que el reloj SysTick tiene una frecuencia de 8 MHz.

Mientras configuraba SysTick, la validacin de interrupcin est establecido en 1.


(suponiendo que los niveles de prioridad son coherentes y la tabla de vectores de
interrupcin est correctamente inicializado) implica que el manejador de interrupcin
correspondiente (SysTick_Handler) de esta excepcin sera la llamada
automticamente. Durante este proceso, una global
214 Assembly Language Programming Appendix B 214

Variable (Time_val) disminuye, permitiendo que el programa principal para iniciar el


temporizador hasta que la variable se ha cancelado.

Algunos comentarios sobre este listado:


- El registro direcciones, as como los valores de las dos frecuencias (la del reloj y
lo que queremos) son "duras", es decir, codificada codificada por constantes, y por lo
tanto corresponden a abordar de inmediato.
- El nmero de lanzamiento (Time_val) est contenida en una mitad-palabra. En el
ejemplo, el valor inicial dado a la variable se usa directamente. Este es tambin el caso
de la funcin Stop_SysTick.
- La funcin arranque, adems de calcular la funcin de recarga, se establece en 1
bits que permiten elegir el reloj interno con el fin de validar las interrupciones y para
iniciar el temporizador. Estos tres parmetros a 1 se realizan por separado tres lgico
"O"s. Una sola "o" es suficiente para hacer esto en una sola operacin.
- Los registros utilizados por los procedimientos no se guardan, a diferencia de los
dems ejemplos mencionados en este libro. Esta operacin no es necesaria en el
caso de la funcin de procesamiento SysTick_Handler. De hecho, los dos registros
utilizados (R0 y R1) forman parte de la lista Guardar contextuales durante el
procesamiento de excepciones de conmutacin. As nunca habr efectos secundarios
ligados al lanzamiento de la SysTick_Handler en este caso.

EJEMPLO B.1.- SysTick biblioteca de programacin

;*************************************************************
; Seccin de datos
;
Zona********************************************
***************** MyData, datos, ALIGN=0
;****************************************************
********* Freq_Quartz EQU 8000000
Freq_Request EQU 100
SysTick_CTRL EQU 0xe000e010
SysTick_LOAD EQU 0xe000e014
SysTick_VAL EQU 0xe000e018
SysTick_CALIB EQU
0xe000e01C Time_VAL DCW
123
;*************************************************************
; Seccin de Programas
;****************************************************
********* MyCode, cdigo de rea, readonly, ALIGN=2
215 Assembly Language Programming Appendix B 215

;************************************************************
*

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SystickSetPeriod PROC
LDR, R1=Freq_Quartz ; leer la frecuencia del reloj
SDIV R2,R1,R0; clculo del nmero n de
; para ciclos de
frecuencia deseada. SUBS R2,R2#1 ; la
modificacin del valor de N - 1
LDR, R3=Systick_LOAD ; de recargar registrarse
STR R2,[R3]
BX LR
ENDP
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Start_SysTick
PROC
Empujar LR
LDR, R0=Freq_Request ; valor de carga del perodo solicitado
LDR, R1=SysTick
STR_VAL R0,[R1]
BL SystickSetPeriod ; la inicializacin de
recargar
LDR, R0=Systick_CTRL
LDR R1,[R0]
ORR R1,R1,#4 ; la eleccin del reloj
ORR R1,R1,#2 ; la autorizacin de interrumpir
ORR R1,R1,#1 ; el lanzamiento del temporizador
STR R1,[R0]
POP PC
ENDP
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Stop_Systick
PROC
LDR, R0=Systick_CTRL
LDR R1,[R0]
BIC R1,R1,#2 ; Desactiva systick
interrumpir
BIC R1,R1,#1 ; detiene el temporizador
STR R1,[R0]
BX LR
ENDP
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
216 Assembly Language Programming Appendix B 216

Handler_SysTick PROC
Exportar SysTick_Handler
LDR, R0= Time_Val; Carga de variable global
LDRH R1,[R0]
SUB R1,#1 ; Decrementacin STRH R1,[R0] ; y el
almacenamiento BX LR
ENDP

EJEMPLO B.2.- El uso de la biblioteca

;*************************************************************

; Seccin de Programas

;*************************************************************

MyCode, cdigo de rea, readonly, ALIGN=2

;*************************************************************

Principales PROC

LDR, R5=time_VAL

Start_Systick BL

R0 LDRH inconclusa,[R5]

CMP, R0#0

BNE inacabado

Stop_Systick BL

Infinito infinito B ; Fin del programa

ENDP
Apndice C

Ejemplo de un archivo de
"Bootstrap"

Este apndice contiene el cdigo y una explicacin de la STM3210x.s archivo


utilizado en el proyecto genrico presentado anteriormente (vase el captulo 9). Este
archivo es un archivo de arranque, lo que nos permite llevar a cabo una mnima la
inicializacin del controlador (aqu un STMicroelectronics STM32F103RB). Este
archivo fue hecha y proporcionada por Keil con sus Vision Development Suite. Su
inclusin (o de una versin diferente o modificada) en un proyecto es necesario para
permitir el desarrollo de un proyecto completo. Como este archivo define los vectores
de interrupcin especficos de la controlador para el que fue escrita, es obvio que si
fue escrito para un procesador diferente un cierto nmero de lneas sera diferente,
eliminado o aadido. Sin embargo, la estructura general se quedara igual.

C.1. El listado

EJEMPLO C.1.- Un archivo bootstrap: STM32F10x.s archivo

;//**************************************************************
;/* STM32F10x.s : archivo de inicio para ST STM32F10x dispositivo
serie */
;//************************************************************ **
;/* < "Usar el Asistente para configuracin en el men de contexto" >
*/
;/* Este archivo es parte de las herramientas de desarrollo uVision/brazo.
*/
;/* Copyright (c) 2005-2007 Keil Software. Todos los derechos
reservados. */
;/* Este software slo pueden ser usados bajo los trminos de un
documento vlido, actual */
;/* KEIL de licencia de usuario final para obtener una versin compatible de
KEIL
218 Assembly Language Programming Appendix C 218

Software */
/* Las herramientas de desarrollo. Nada le da derecho a utilizar
este software. */
;//**************************************************************
;//**************************************************************
;// <h> Configuracin de pila
;// <o> Pila Tamao (en bytes) <0x0-0xFFFFFFFF :8>
;// </h>
;//**************************************************************
STACK_SIZE EQU 0x00000200
Pila de rea, NOINIT, READWRITE ALIGN=3
Stack_mem Espacio inicial
STACK_SIZE_sp

;//**************************************************************
;// <h> Configuracin del montn
;//> <o Heap Tamao (en bytes) <0x0-0xFFFFFFFF
:8>
;// </h>
;//**************************************************************
HEAP_SIZE EQU 0x00000000
rea HEAP, NOINIT, READWRITE ALIGN=3
Heap_base
Heap_Mem espacio heap HEAP_SIZE_limit
Conservar8
Pulgar

;//**************************************************************
; tabla vectorial asignado a la
direccin 0 en el
rea de reset reset,
VectorsD DATOS
CD
READONLY
initial_sp;
parte Vectores de
superior de
exportacin
StackDCD
Reset_Han
dler;
Restablece
r
HandlerD
CD
nmi_Hand
ler; NMI
HandlerD
CD
HardFault
_Handler;
Incidente
duro
HandlerD
CD
MemMana
ge_Handle
219 Assembly Language Programming Appendix C 219

DCD DCD reservado


0 ; 0 ; Reservados DCD DCD reservado 0 ; 0 ; reservados
DCD SVC_Handler Handler SVCall ;
DCD DebugMon_Handler ; Controlador de Monitor de depuracin
DCD 0 ;
reservados
DCD PendSV_Handler Handler PendSV ;
DCD SysTick_Handler Handler SysTick ;

; interrupciones externas
DCD _WWDG IRQHandler ; Vigilante de ventana
DCD _PVD IRQHandler ; PVD mediante lnea EXTI
Detecta
r
DCD _IRQHandler ; tamper antisabotaje
DCD RTC_IRQHandler ; RTC_FLASH ; IRQHandler
DCD DCD Flash RCC_IRQHandler ; RCC
EXTI DCD0_IRQHandler ; EXTI LNEA 0
EXTI DCD1_IRQHandler ; EXTI LNEA 1
EXTI DCD2_IRQHandler ; EXTI LNEA 2
EXTI DCD3_IRQHandler ; EXTI LNEA 3
EXTI DCD4_IRQHandler ; EXTI LNEA 4
DCD 1_DMAChannel IRQHandler ; canal DMA 1
DCD 2_DMAChannel IRQHandler ; canal DMA 2
DCD 3_DMAChannel IRQHandler ; canal DMA 3
DCD 4_DMAChannel IRQHandler ; canal DMA 4
DCD 5_DMAChannel IRQHandler ; canal DMA 5
DCD 6_DMAChannel IRQHandler ; canal DMA 6
DCD 7_DMAChannel IRQHandler ; canal DMA 7
DCD _ADC IRQHandler ; ADC
DCD USB_HP_CAN_TX_IRQHandler ; USB de alta prioridad DCD
USB_LP_CAN_RX0_IRQHandler ; USB de baja prioridad DCD
PUEDE_RX1_IRQHandler ; puede RX1
DCD PUEDE_SCE_IRQHandler ; puede SCE
EXTI DCD9_5_IRQHandler ; EXTI Lnea 9..5
TIM DCD1_BRK_IRQHandler ; TIM1 romper
220 Assembly Language Programming Appendix C 220

DCD TIM1_UP_IRQHandler ; TIM1 Actualizar


DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger
DCD TIM1_CC_IRQHandler ; TIM1 Capturar comparar
DCD TIM2_IRQHandler ; TIM2
DCD TIM3_IRQHandler ; TIM3
DCD TIM4_IRQHandler ; TIM4
DCD I2C1_EV_IRQHandler ; I2C1 Evento
DCD I2C1_ER_IRQHandler ; I2C1 Error
DCD I2C2_EV_IRQHandler ; I2C2 Evento
DCD I2C2_ER_IRQHandler ; I2C2 Error
DCD SPI1_IRQHandler ; SPI1
DCD SPI2_IRQHandler ; SPI2
DCD USART1_IRQHandler ; USART1
DCD USART2_IRQHandler ; USART2
DCD USART3_IRQHandler ; USART3
DCD EXTI15_10_IRQHandler ; EXTI Lnea 15..10
DCD RTCAlarm_IRQHandler ; Alarma de RTC
DCD USBWakeUp_IRQHandler ; Activacin de USB

;//**************************************************************
AREA |.texto|, Cdigo, READONLY
Reset_Handler PROC
Exportar Reset_Handler [principal]
Importacin dbiles
LDR, R0 = principal
BX R0
ENDP

; Dummy controladores de excepcin (bucles


infinitos que pueden modificarse)
NMI_Handler PROC
Exportar nmi_Handler dbil [B] .
ENDP
HardFault_Handler
PROC
Exportar HardFault_Handler dbil [B] .
221 Assembly Language Programming Appendix C 221

ENDP
MemManage_Handler
PROC
Exportar MemManage_Handler dbil [B] .
ENDP
BusFault_Handler
PROC
Exportar BusFault_Handler dbil [B] .
ENDP
UsageFault_Handler
PROC
Exportar UsageFault_Handler dbil [B] .
ENDP
SVC_Handler PROC
Exportar SVC_Handler dbil [B] .
ENDP
DebugMon_Handler
PROC
Exportar DebugMon_Handler dbil [B] .
ENDP
PendSV_Handler PROC
Exportar PendSV_Handler dbil [B] .
ENDP
Handler_SysTick
PROC
Exportar SysTick_Handler dbil [B] .
ENDP

Default_Handler PROC
222 Assembly Language Programming Appendix C 222

Exportar WWDG_IRQHandler [Exportar] dbil_PVD


IRQHandler [Exportar] dbil_sabotaje IRQHandler
[Exportar] DBIL RTC_IRQHandler [dbil] Exportar
Flash_IRQHandler [Exportar] DBIL
RCC_IRQHandler [Exportar] DBIL
EXTI0_IRQHandler [Exportar] DBIL
EXTI1_IRQHandler [Exportar] DBIL
EXTI2_IRQHandler [Exportar] DBIL
EXTI3_IRQHandler [Exportar] DBIL
EXTI4_IRQHandler [Exportar] dbil
DMAChannel1_IRQHandler [Exportar] dbil
DMAChannel2_IRQHandler [Exportar]
dbil3_DMAChannel IRQHandler [Exportar]
dbil4_DMAChannel IRQHandler [Exportar]
dbil5_DMAChannel IRQHandler [Exportar]
dbil6_DMAChannel IRQHandler [Exportar]
dbil7_DMAChannel IRQHandler [Exportar] DBIL
ADC_IRQHandler [Exportar] DBIL
USB_HP_CAN_TX_IRQHandler [Exportar] DBIL
USB_LP_CAN_RX0_IRQHandler [Exportar] dbil
puede_RX1_IRQHandler [Exportar] dbil
puede_SCE_IRQHandler [Exportar] DBIL
EXTI9_5_IRQHandler [Exportar] DBIL
TIM1_BRK_IRQHandler [Exportar] DBIL
TIM1_UP_IRQHandler [Exportar] DBIL
TIM1_TRG_COM_IRQHandler [Exportar] DBIL
TIM1_CC_IRQHandler [Exportar] DBIL
TIM2_IRQHandler [Exportar] DBIL
TIM3_IRQHandler [Exportar] DBIL
TIM4_IRQHandler [Exportar] DBIL
I2C1_EV_IRQHandler [Exportar] DBIL
I2C1_ER_IRQHandler [Exportar] DBIL
I2C2_EV_IRQHandler [Exportar] DBIL
I2C2_ER_IRQHandler [Exportar] DBIL
SPI1_IRQHandler [Exportar] DBIL SPI2_IRQHandler
[dbil]
223 Assembly Language Programming Appendix C 223

Exportar USART1_IRQHandler [Exportar] DBIL


USART2_IRQHandler [Exportar] DBIL
USART3_IRQHandler [Exportar] DBIL
EXTI15_10_IRQHandler [Exportar] dbil
RTCAlarm_IRQHandler [Exportar] dbil
USBWakeUp_IRQHandler [dbil]
WWDG_IRQHandler_PVD ANTISABOTAJE IRQHandler
IRQHandler_RTC_FLASH_IRQHandler IRQHandler
RCC_IRQHandler EXTI0_IRQHandler
EXTI1_IRQHandler EXTI2_IRQHandler
EXTI3_IRQHandler EXTI4_IRQHandler IRQHandler
DMAChannel DMAChannel1_2_3_DMAChannel
IRQHandler IRQHandler DMAChannel4_IRQHandler
DMAChannel5_IRQHandler
DMAChannel6_IRQHandler7_DMAChannel IRQHandler
IRQHandler ADC_USB_HP_CAN_TX_IRQHandler
USB_LP_CAN_RX0_IRQHandler
CAN_RX1_CAN_IRQHandler SCE_IRQHandler
EXTI9_5_IRQHandler TIM1_BRK_IRQHandler
TIM1_UP_IRQHandler TIM1_TRG_COM_IRQHandler
TIM1_CC_IRQHandler TIM2_3_IRQHandler IRQHandler
TIM TIM4_IRQHandler
224 Assembly Language Programming Appendix C 224

I2C1_EV_IRQHandler
I2C1_ER_IRQHandler
I2C2_EV_IRQHandler
I2C2_ER_ 1_IRQHandle
r IRQHandler SPI
SPI2_IRQHandler USAR
T1_IRQHandler
USART2_IRQHandler
USART3_IRQHandler EX
TI15_10_IRQHandler RT
CAlarm_IRQHandler
USBWakeUp_IRQHandler

B .
ENDP

Pila La pila inicial de usuario ;

Si :DEF : MICROLIB ;- - - - - - - - - Exportacin


initial_sp
Heap_basev exportacin
Exportar heap_limit

Ms ;- - - - - - - - -
IMPORT use_DOS_region_memory
Exportar usuario_initial_stackheap
user_initial_stackheap LDR, R0 = Heap_mem
LDR, R1 =(stack_Mem + STACK_SIZE) LDR,
R2 = (heap_Mem + HEAP_SIZE) LDR, R3 =
Stack_mem
BX LR

ENDIF ;- - - - - - - - -
225 Assembly Language Programming Appendix C 225

C.2. Puntos
importantes

Este listado requiere alguna explicacin, incluso si su uso ciego no causa


problemas importantes:
- En esta versin, el sistema pila (Stack_Mem) es 512 bytes de dimensin. La parte
superior de la pila est marcada con initial_stack, que es la primera direccin que
sigue a la zona reservada como la pila del sistema es pre-decremento.
- un montn (heap_Mem) est reservado en la misma manera como la reserva de
la pila del sistema. Esta reserva es para el uso de la biblioteca estndar de C
(compilador). Es interesante observar, sin embargo, que en este caso la reserva es
totalmente ficticio porque el tamao (HEAP_SIZE) reservado es cero. Slo est all
para evitar causar errores de resolucin durante el enlace Editar.
- La tabla de vectores de interrupcin corresponde a un conjunto de palabras se
inicializa con las direcciones de las rutinas de procesamiento de excepciones que
existen en el mdulo inferior. Comienza por almacenar la direccin superior de la pila
declarada anteriormente. El STM32 utilizada en este proyecto est construido
alrededor de 43 vectores de interrupcin.
- El manejador de interrupcin establecido est limitada a un solo B., o un bucle
infinito. Este mdulo es, por tanto, slo un simple esqueleto para el desarrollo de
rutinas ms adaptado. Estas rutinas son realmente pozos: si una excepcin es lanzada
y nada sino el esqueleto ha sido desarrollado, es imposible escapar a otros que
por Restablecer.
- Las excepciones externos (que corresponden a las interrupciones) estn
agrupados en la misma rutina. Esta rutina tiene unos 43 nombres diferentes. Todos
estos nombres son dbiles (otra declaracin ser prioridad sobre ellos) y exportados
para ser visibles desde otros mdulos.
- Restablecer el handler es el nico que contiene un poco de cdigo. Simplemente llama al
La rutina principal, que es el punto de entrada a la librera MicroLib. Esta misma
rutina terminar por un salto a la etiqueta , que es el principal punto de entrada del
proyecto. La fuente MicroLib no es directamente accesible; pero abriendo una ventana
Desensamblador en modo de depuracin, es posible visualizar su contenido.
- Al final de la lista son conductos que permiten la exportacin de las direcciones
de la pila y el heap, en particular para la librera MicroLib si est incluido en
el proyecto. De lo contrario (ELSE ) alternativo, se supone que la biblioteca estndar
se utiliza, en cuyo caso el usuario_initial_stackheap procedimiento es necesario
para su correcta ejecucin y por donde se exporta. Este procedimiento llena
el R0 a R3 se registra con las direcciones de reserva delimitaciones de la pila y el
montn.
Apndice D

El Ensamblador
GNU

El conjunto de ejemplos presentados en este trabajo estn escritos para el brazo


del Kit de desarrollo de microcontrolador (MDK). Otro compilador/ensamblador/link
editor tro, sin embargo, actualmente se utiliza para la construccin de dichos
proyectos. Esta es la cadena de compilacin GNU 1-Conexin del compilador GCC
(GNU), que como su nombre lo indica procede del mundo del software libre y
cooperativo. Este apndice se basa especficamente en la Sourcery g++ Lite tools para
ARM EABI (Embedded-Application Interfaz Binaria). Esta precisin es importante
en la medida en que, aunque las herramientas estn diseadas para ser genrico,
todava tienen especificidades y particularidades que les hacen algo ms difcil de
entender y usar. Como un ejemplo para ilustrar esto, tome la documentacin oficial
de la Sourcery g++ ensamblador. Esta documentacin es 328 pginas de largo, y 202
pginas (captulo 9) estn dedicados a las caractersticas exclusivas de cada
procesador. A pesar de las peculiaridades, es interesante para dibujar sobre los puntos
comunes entre los diferentes compiladores GNU/montadores y editores de enlace a
fin de poder desarrollar programas con diferentes herramientas y/o procesadores.

El brazo-MDK y GNU GCC-proyectos no son compatibles entre los dos modelos,


que podra parecer sorprendente, ya que el procesador y, por lo tanto, el conjunto de
instrucciones son muy similares. Las dos principales diferencias se encuentran en la
sintaxis utilizada para las directivas (por el ensamblador) y en la forma de describir
la memoria (para el editor de enlaces). Debemos tener en cuenta que el uso de la
herramienta GNU GCC es todava posible en el Keil visin favorable, que es
interesante como este entorno es completamente funcional en su versin de prueba
gratuita y por lo tanto es posible utilizar el emulador de controlador que ofrece.

1 GNU es un Unix como sistema operativo del ordenador y corresponde al acrnimo


recursivo de "GNU No es Unix"
228 Assembly Language Programming Appendix D 228

En la primera parte de este apndice, vamos a enumerar las principales directivas


necesarias para desarrollar un proyecto, por ejemplo, que se presentan en el Captulo
3. En la seccin D.2 le daremos un ejemplo de un programa escrito con estas reglas de
sintaxis que pretende compensar la ausencia de la librera MicroLib. No vamos a
desarrollar los aspectos vinculados al vinculador y, especialmente, el archivo de
descripcin de la memoria, debido a la complejidad de su construccin. La Sourcery
g++ suite para ARM EABI se suministra con los tpicos archivos (generic.ld por
ejemplo) desde la cual es posible iniciar.

D.1. Directiva de GNU

En el mundo GNU, el conjunto de instrucciones que queremos dar al compilador


o general (Directivas) ser introducida por una palabra clave precedida por un "."
(punto). La gran mayora de las directivas que hemos explorado (vase el captulo 3)
tienen sus equivalentes directos en esta versin del ensamblador, pero hay un cierto
nmero de adiciones, diferencias y sutilezas que debemos entender cuidadosamente
cuando se cambia desde el universo del brazo al universo GNU.

D.1.1. Generalidades

Estos no son estrictamente las directivas mencionadas, pero las siguientes reglas
sintcticas deben respetarse para producir cdigo que sea aceptable para el
ensamblador:
- los comentarios son, como es habitual en C, el conjunto de caracteres entre los
delimitadores '/*' y '*/'. El usuario tiene una segunda oportunidad para insertar un
comentario insertando una '@'. El resto de la lnea (hasta el retorno de carro) entonces
ser ignorado. Esta segunda sintaxis es inevitablemente no muy legible;
- smbolos estn compuestas de varios "carta" caracteres (maysculas o
minsculas), el "nmero" de caracteres (con la excepcin del primer carcter) y los
dos caracteres especiales '.' y '_'. Por favor tenga en cuenta que elcarcter '$', que est
permitido en otros procesadores, no se puede utilizar aqu porque (como #) que indica
el inicio de un valor inmediato.
- Una etiqueta es un smbolo seguido de un ':';
- no hay diferencias a la hora de dar la expresin de un valor numrico distinto de
expresin en cualquier base numrica. Slo las bases 10, 16 y binarios estn
permitidos. Para nmeros binarios, el valor debe ser con el prefijo 0b. Por ejemplo, la
instruccin mov R0, #0b100 se carga el valor 4 en R0.
229 Assembly Language Programming Appendix D 229

D.1.2. Gestin de memoria

No hay una nica directiva para crear secciones. Hay tres directivas que nos
permiten realizar las aberturas (cierres pasar automticamente con la apertura de una
nueva seccin). Estos se identifican por el tipo de seccin que se cree:
- .El texto nos permite abrir una seccin de cdigo.
- .data nos permite abrir una seccin de datos inicializados;
- .bss nos permite abrir una seccin de datos inicialmente ajustado a cero.

Estas directivas no admite ciertas opciones, a diferencia de la directiva del brazo


de la zona. No obstante, es posible agregar otras directivas para la seccin apertura
suite para especificar las propiedades especficas:
- .alinear n nos permite imponer una alineacin en la instruccin o dato que sigue
esta directiva. La alineacin ser una direccin divisible por 2 n;
- .ltorg nos permite especificar que el contenido literal de la piscina debe colocarse
en esta seccin (que debe ser de . Tipo de texto).

D.1.3. Gestin de variables

Las diferentes directivas que siguen nos permiten hacer varias reservas. No hay
que olvidar que los smbolos que corresponden a esas reservas deben, como para las
etiquetas, estar seguido por ':':
- .la "cadena ascii..." hace una reserva de tantos bytes como hay caracteres en la
cadena despus de esta directiva. Tenga en cuenta que una versin .asciiz existe y est
configurado en 0 al final de la cadena.
- .byte exp1{,exp2}{...} se reserva un byte inicializado por exp. Hay tantas reservas
como expresiones;
- .equ smbolo, expresin acta como un hallazgo (smbolo)/reemplazar
(expresin) en el mdulo actual. Por consiguiente, esta directiva nos permite definir
constantes;
- .Fill repetir {,tamao}{,valor} nos permite crear copias de repetir el
valor valor codificado en tamao de bytes. Si el valor no est definido, el valor ser
cero. Si no se especifica tamao, el tamao predeterminado ser de un byte.
- .hword exp1{,exp2}{...} es equivalente a .byte para reservas de 16 bits (una media
palabra);
230 Assembly Language Programming Appendix D 230

- .el tamao del espacio {,llenar} se reserva bytes de tamao lleno


de relleno (menos de 255). La ausencia de relleno lleva a la inicializacin en 0.
- .palabra exp1 {,exp2}{...} es equivalente a .byte para reservas de 32 bits.

D.1.4. Condicionado general

Las siguientes directivas nos permiten llevar a cabo condicionado general (vase la seccin
3.5.2):
- .si la expresin significa que las lneas que siguen se incluirn en la seccin si
Expresin no es falso.
- .endif marca el final de la parte condicional;
- .else nos permite incluir una alternativa compuesta con .Si.

D.1.5. Miscelnea

Existen otras directivas que pueden ser necesarios o tiles:


- Un mdulo finaliza con .final. El ensamblador ignora las lneas que siguen a esta
directiva.
- La directiva .type nos permite dar informacin adicional sobre un smbolo. Esta
informacin puede ser particularmente til con el uso de un depurador simblico. El
uso ms comn es .el tipo de smbolo,%funcin para indicar que la
etiqueta smbolo corresponde a un procedimiento de entrada.
- no hay directivas especficas para indicar la importacin de un smbolo (vase la
seccin 9.1.5). Es suficiente, en el mdulo donde la insercin de la directiva .smbolo
mundial es declarado, ese smbolo es compartida con otros smbolos del mismo
nombre durante el enlace Editar. Esta directiva lleva a cabo la exportacin de un
smbolo.
- .dbiles marcas de nombre el nombre del smbolo como dbil en la tabla de
smbolos. Esto significa que otra definicin del smbolo tendr una prioridad ms alta
que esta declaracin escrita.
- .Nombre de tamao de expresin, asocia un tamao (expresin) con un smbolo
(nombre). La dimensin puede ser el resultado de un clculo, tales como la diferencia
entre dos smbolos. Esta directiva se utiliza normalmente para calcular, por ejemplo,
cunto espacio ocupa una funcin. Por ejemplo, .tamao Dim . - Deb_func asignar la
dimensin correspondiente a la diferencia entre la actual direccin (.) y la direccin del
smbolo deb_func al smbolo Dim.
231 Assembly Language Programming Appendix D 231

D.2. El programa bootstrap

El uso de GNU GCC representa el uso de MicroLib nulas. En comparacin con


otros proyectos desarrollados en lenguaje ensamblador, la funcin principal de esta
biblioteca que debemos considerar es la rutina que nos permite, despus de
un restablecimiento, por ejemplo, para reinicializar las variables inicializadas
(principalmente en el RW o zonas .DATA), as como de restablecer las otras zonas a
cero (la Zi o .bss zonas).

La inclusin (ver ejemplo D.1) es un ejemplo de una rutina que lleva a cabo estas
inicializaciones. El principio es muy simple, ya que se trata de hacer transferencias de
memoria a memoria (inicializar variables) o restablecimiento de otras zonas
( variables simples). Qu puede ser ms oscuro es la forma en que es posible
recuperar las direcciones y tamaos de estas diferentes zonas. En nuestro caso, que
por cierto es bastante estndar, el Startup_constants tabla que contiene esta
informacin se compone de nombres genricos creados en los archivos de descripcin
de la memoria utilizada por el vinculador. Los nombres de estas direcciones son lo
suficientemente significativas para pasar el comentario. El
prefijo cs significa CodeSourcery.

EJEMPLO D.1.- mdulo de inicializacin de variables de entorno (GNU)

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Nombre : Inicio.asm
Propsito : Sistema de inicializacin de variables y se inicializa la pila
Versin : V1.1
Autor : SDM (INSA de Toulouse)
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
.text
.Alinee 2
.inicio global
.Escriba startup, %funcin
Inicio : ;la inicializacin de pila
LDR R0, Startup_constants+12
MOV SP, R0
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Inicializacin de variables inicializadas
R0 : @Destination, R1 : @Source, R2 : size, R3 : counter, R4 : time
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Start_init_RAM:
LDR R0, Startup_constants+16
232 Assembly Language Programming Appendix D 232

LDR R1, Startup_constants+20


LDR R2, Startup_constants+24
MOV R3, #0
Loop_init_ra :
m
CMP R3, R2
BCS Start_ZERO_ram
LDR R4,R1,#0]
STR R4,R0,#0]
Agreg R3, #4
ar
Agreg R1, #4
ar
Agreg R1, #4
ar
Agreg R0, #4
ar
B loop_init_ram

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Inicializacin de
variables no inicializadas a cero
R0 : @Destination, R2 : size, R3 : counter, R4 : time
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Start_ZERO_ram :
LDR R0, Startup_constants+0
LDR R2, Startup_constants+8
MOV R3, #0
MOV R4, #0
loop_ZERO_ram :
CMP R3, R2
BCS principal
llamada_ STR [
R4,
R0,#0] Aadir R3,
#4
Agregar R0, #4
B loop_ZERO_ram
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - el final de la rutina de
inicializacin, principal llamada
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Call_main : BL principal
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
233 Assembly Language Programming Appendix D 233

Constantes utilizadas por el inicio


Almacenados en la seccin .text, despus de la rutina
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
.text
Startup_constantes :
.palabra cs3_region_start_sev
.palabra cs3_region_ZERO_ram_loadaddr
.palabra cs3_region_ZERO_ram_size
.palabra cs3_stack
.palabra cs3_region_start_data
.palabra cs3_region_init_ram_loadaddr
.palabra cs3_region_init_ram_size
.final

Un segundo anuncio (ver ejemplo D.2) es un ejemplo de un archivo bootstrap.


Corresponde y es comparable a la que ya hemos presentado (vase el apndice C). No
hemos descrito el mdulo completo aqu. De hecho, parte de la tabla de vectores de
interrupcin ha sido deliberadamente excluidos para hacer este listado ms ligeros.

EJEMPLO D.2.- archivo Bootstrap para un ensamblador GNU

//******************************************************************
/* STM32F10x.s : archivo de inicio para ST STM32F10x dispositivo serie
*/
//***********************************************************
/* Versin : CodeSourcery Sourcery g++ Lite (con CS3) */
/* modificado por SDM (llamada a Inicio) */
//******************************************************************

//******************************************************************
La configuracin de la pila /* */
//******************************************************************
.equ STACK_SIZE, 0x00000200
.data
.alinear 3
.globl cs3_stack_mem
.globl cs3_STACK_SIZE
234 Assembly Language Programming Appendix D 234

_ _cs3_stack_mem :
.Si el STACK_SIZE
.espacio STACK_SIZE
.endif
.tamao cs3_stack_mem, . - cs3_stack_mem
.set cs3_stack_size . - cs3_stack_mem
//******************************************************************
/* */ Configuracin de montn
//******************************************************************

.equ HEAP_SIZE, 0x00001000

.data
.alinear 3
.globl cs3_heap_start
.globl cs3_heap_end
Cs3_heap_start :
.Si el HEAP_SIZE
.El espacio HEAP_SIZE
.endif
Cs3_heap_end :
//******************************************************************
Tabla de vectores /* */
//******************************************************************
.seccin ".cs3.interrupt_vector"
.globl cs3_interrupt_vector_cortex_m
.tipo cs3_interrupt_vector_cortex_m,
Cs3_interrupt_vector_cortex_m :
.palabra cs3_stack /* */ la parte superior de la pila
.palabra cs3_reset /* */ controlador de Reset
.palabra nmi_Handler : manejador de NMI /* */
.palabra HardFault_Handler duro /* */ controlador de errores
.palabra MemManage_Handler /* */ controlador fallo MPU
.palabra BusFault_Handler /* */ controlador de errores de bus
.palabra UsageFault_Handler /* */ controlador de errores de uso
.palabra reservada 0 /* */
.palabra reservada 0 /* */
235 Assembly Language Programming Appendix D 235

.palabra reservada 0 /* */
.palabra reservada 0 /* */
.palabra SVC_Handler Handler SVCall /* */
.palabra DebugMon_Handler /* */ controlador de Monitor de depuracin
.palabra reservada 0 /* */
.palabra PendSV_Handler Handler PendSV /* */
.palabra SysTick_Handler Handler SysTick /* */
//******************************************************************
/* */ interrupciones externas
//******************************************************************
.palabra WWDG_IRQHandler /* */ Vigilante de ventana
.palabra EVP_IRQHandler /* PVD mediante EXTI
detectar lnea */
...
Tabla incompleta....
.tamao __cs3_interrupt_vector_cortex_m, . -
cs3_interrupt_vector_cortex_m
//******************************************************************
Controlador de Reset /* */
//******************************************************************
.text
.globl cs3_reset_cortex_m
.tipo cs3_reset_cortex_m, %funcin
Cs3_reset_cortex_m :
LDR, R0=Inicio
BX R0

.tamao cs3_reset_cortex_m,.- cs3_reset_cortex_m

.text
//******************************************************************
Controladores de excepcin /* */
//******************************************************************
.dbil nmi_Handler
.Escriba nmi_Handler, %funcin
NMI_Handler :
B .
.tamao nmi_Handler, . - NMI_Handler
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
236 Assembly Language Programming Appendix D 236

.dbil HardFault_Handler
.escriba HardFault_Handler, %funcin
Handler_HardFault :
B.
.tamao HardFault_Handler, . - HardFault_Handler
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
.dbil MemManage_Handler
.escriba MemManage_Handler, %funcin
Handler_MemManage :
B .
.escriba MemManage_Handler, . - MemManage_Handler
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
.dbil BusFault_Handler
.escriba BusFault_Handler, %funcin
Handler_BusFault :
B.
.escriba BusFault_Handler, . - BusFault_Handler
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
.dbil UsageFault_Handler
.escriba UsageFault_Handler, %funcin
Handler_UsageFault :
B.
.escriba UsageFault_Handler, . - UsageFault_Handler
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
. SVC_Handler dbil
.tipo SVC_Handler, %funcin
SVC_Handler :
B .
.tipo SVC_Handler, . - SVC_Handler
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
.dbil DebugMon_Handler
.escriba DebugMon_Handler, %funcin
Handler_DebugMon :
B .
.escriba DebugMon_Handler, . - DebugMon_Handler
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
.dbil PendSV_Handler
237 Assembly Language Programming Appendix D 237

.escriba PendSV_Handler, %funcin


Handler_PendSV :
B .
.escriba PendSV_Handler, . -
PendSV_Handler
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
.dbil SysTick_Handler
.escriba SysTick_Handler, %funcin
Handler_SysTick : B .
.escriba SysTick_Handler, . -
SysTick_Handler
//***********************************************************
*******
/* */ Controladores IRQ
//***********************************************************
*******
.Default_Handler global
.Escriba default_handler, %funcin
Default_Handler : B .
.Escriba default_handler, . -
Default_Handler
Bibliografa

Brazo [06a] UnaRM, ARMv7M en el nivel de aplicacin manual de referencia, el brazo limitada,
Cambridge,
2006.
Brazo [06b] UnaRM, ARMv7-M Architecture Reference Manual, el brazo limitada, Cambridge,
2006.
Brazo [06c] UnaRM, Cortex-M3 Technical Reference Manual, el brazo limitada, Cambridge,
2006. [10] Una BRAZORM, herramientas de compilacin de RealView - Ensamblador, el
brazo gua limitada, Cambridge,
2010.
[COD] CODASOURCERY, http://www.codesourcery.com.
[KEI] KEIL, http://www.keil.com.
YIU [07] YIU J., La Gua Definitiva para el ARM Cortex-M3, Elsevier, Amsterdam, 2007.
ndice

Argumentos, 2, 26, 37, 40, 104, 119,


Un 121-131, 133, 134, 136-138, 142,
143, 146
El privilegio de acceso, 16
Tabla ASCII, 36
ADC, 52, 66, 201, 217,
ASR, 52, 70, 75, 201
Agregar, 30, 33, 49, 50, 52, 64, 67,
Ensamblador, 1, 2, 25-28, 30, 32, 36-39,
80,
41, 43-45, 48-51, 53-55, 57- 59, 63,
100, 129, 134, 137, 140, 143, 177,
64, 78, 79, 88, 130, 133, 149, 151,
201, 231
173, 178-190, 197, 227, 228, 230,
El modo de direccionamiento, 32,
233
47, 57, 59 a 61,
general
100, 111, 114, 127, 134, 142
Por piezas, 178
algoritmo, 61, 87, 88, 91, 92, 94,
La directiva, 9, 25, 111, 175,
99,
idioma, 1, 2, 4, 6, 9, 15, 17, 22,
103, 109, 112
24-30, 32, 35, 39, 41, 47, 58,
algorithmic
61, 84, 87-89, 91, 94, 95, 101,
Estructuras alternativas, 79, 89
103, 106-112, 120, 123, 125,
alternativa completa, 90-93,
136, 146, 175, 181, 182, 196,
97, 98 estructuras iterativas
231
Eleccin mltiple, 94
Alternativa simple, 89-91, 93
estructuras, 24, 44, 65, 76, 77, B
79, Cco, 30, 33
88 La BFC, 70, 202
Alinear, 40, 56, 92, 96, 100, 101, BFI, 70, 202
121, 128, 214, 215, 216, 217 BIC, 70, 52, 202, 214
Y, el 52, 65, 70, 77, 106-111, 157 bits
201, 202, 207 Las bandas,
Anexo puntero, 134, 137, 138, 143, cambio 10,
144 64, 85
rea, 28, 33, 35, 41, 43, 56, 92, 96,
100, 101, 121, 128, 136, 149, 176,
177, 183, 214, 216, 217, 229
242 Assembly Language Programming Index 242

BL, 20, 21, 26, 35, 43, 44, 51, 56, 65, D
78, 92, 93, 95, 104, 105, 119-121,
Datos
123-125, 129, 132, 134, 140, 176,
Cadena, 36, 38, 94, 95, 175, 185,
183, 187, 202, 214, 216, 231
193, 227, 229,
BLX, 78, 96, 97, 202
113 de registro
bus
Seccin, 36, 47, 98, 136, 176, 179,
(AHB), 5
180, 185, 189, 196
AHB-Lite, 5
Pila, 1, 18-20, 27, 40, 41, 51, 81,
Fallo, 77, 153-156, 158, 161, 167,
83, 85, 115 - 117, 120, 126-131,
170, 217,
133, 134, 136, 137, 139, 140,
233, 5, 6 matriz
142-144, 148, 149, 157, 168,
El MPP, 5
169, 182, 191, 217, 225, 231,
BX, 20, 21, 26, 35, 51, 56, 65, 77, 78,
233
96, 105, 119-121, 124, 125, 129,
Estructura, 32, 60, 61, 111, 114
132, 134, 137, 140, 143, 150, 155,
DCI 41
157, 169, 177, 202, 214, 217, 233,
Estado de depuracin, 16, 17
C Depurador, 77, 174, 185, 197, 230
Llevar la bandera C, 52, 70, 71 la depuracin, 9, 85, 87, 158, 188-
CBNZ, 79, 202 190,
CBZ, 79, 202 196, 198
Lista encadenada, 143, 145 Desmontaje, 25, 26, 54, 225
CLRX, 85 doble
CLZ, 71, 202 Direccionamiento
CM3Core, 3, 15 indirecto, 97, 131,
CMN, 76, 52, 202 59, 131 sealador
CMP, 52, 65, 66, 76, 79, 89, 90-93, Osd, 85
95, 99, 100, 103-105, 107-111, DWT, 6
121, 124, 125, 129, 132, 134, 157, dinmica
202, 216, 231 Asignacin de
del cdigo datos, 114,
Direccin, 22, 198 111, 127
Seccin, 57, 179, 180, 185, 189
Comn, 40, 41, 136, 196, 106-111 E, F, G
condicin condicin compuesta, 64
a 66, 76, 79, 88, 90, 98 EOR, 52, 71, 202
99, 102, 106-109 EQU, 30, 39, 40, 48, 128, 179, 214,
condicionado 217
General, 43 jump, El ETM, 6
65, 89, 102 Exportacin, 39, 45, 149, 150, 151, 176,
CPD, 85 177, 181-183, 214, 217
CPS, 85 externo
Desarrollo transversal, 196 La modularidad, 88,
175, 180 de
referencia
Archivo, 2, 25, 27, 28, 39, 42, 44, 48, 88,
173, 175, 178, 179, 182 a 185, 187-
197, 217, 228, 233
243 Assembly Language Programming Index 243

Bandera Q (saturacin), 68, 69 L


Flash, 6, 9, 18, 189, 194, 197, 217
Etiqueta, 26, 29, 30, 34, 36, 40-43, 45,
FPB, 6
48, 57, 75, 78, 79, 81, 83, 88, 89,
GBLS, 43
96, 100, 106, 186, 187, 192, 193,
Obtenga, 42
201-203, 225, 228,
H, I, J, K 230, 169 de llegada
tarda, 170
Modo de handler, 15, 16, 19, 168,
LDM, 58, 78, 82, 84, 85, 131, 134,
169 heap, 40, 126-128, 136, 217,
203
225, 233, 26, 29 identificador
LDMDB, 82-84, 203
Operando inmediato, 47, 53-55, 63,
LDR, 33, 34, 47, 54-58, 60, 61, 77,
73
78, 81, 92, 93, 96, 97, 100-102,
Importacin, 39, 45, 150, 176, 177,
121, 124, 125, 128-132, 134, 137,
180-
183, 217 140, 143, 146, 150, 157, 169, 176,
indirectos 177, 183, 186, 187, 203, 214, 216,
Direccionamiento con 217, 231, 233
desplazamiento, 60 LDRB, 33, 34, 58, 81, 101, 102, 104,
direccionamiento con ndice, 112 105, 157, 163, 177
Inicializa la variable, 37, 39, 231, LDRBT, 58, 85
instruccin, 1-3, 6, 9, 16, 18-27, LDRD, 58, 83, 203, 204
29- LDREX, 85
32, 34, 35, 38, 44, 47-55, 57-61, LDRH, 58-62, 81, 177, 214, 216
63 a 71, 73, 75-85, 87-89, 93, LDRSB, 58, 81
95- LDRSBT, 85
97, 100, 105, 106, 119, 120, 123, LDRSH, 58, 81
131, 134, 137, 138, 140, 147, 149, LIFO, 115, 117, 120, 126, 127
153-158, 167-169, 173, 179, 182, literal
185-187, 197, 201, 202, 227-229 Expresin, 37, 38, 48,
puntero, 20, 21, 35, 51, 54, 78, 55, 56 la piscina
81, Little endian, 10
119, 149, 167-169 Cargar/guardar la arquitectura,
modularidad interior, 88, 178, 32, cargador de 104, 39, 174,
interrumpir, 4, 9, 15, 18, 23, 82, 192, 196, 197 los datos locales,
86 1, 136, 137
147-150, 152, 158-162, 166, 167, LSL, 52, 61, 71, 75, 80, 81, 96, 97,
169, 171, 175, 181, 188, 192, 197, 111, 163, 203, 204, 206, 207
209-214, 217, 225, 233 LSR, 52, 71, 75, 79, 204
Tabla de vectores, 152, 181, LTORG, 39, 55-57
188, 192,
213, 225, 233 M
ISB, 85 MCR, 85
Ella, 23, 24, 64, 65, 79, 88, 106, 131, MCRR, 86
170, 202
ITM, 6
JTAG, 6, 197, 198
Mantener, 42, 180
244 Assembly Language Programming Index 244

La memoria PLD, 86
Direccin, 9, 13, 21, 29, 32, 39, 97, PLI, 86
147-149, 154, 170, 182, 192, POP, 78, 84, 104, 105, 120, 121, 124,
193, 153 Fallo de gestin 125, 129, 132-134, 137, 140, 143,
El MLA, 67 169, 205, 214
MLS, 67 Conservar8, 41, 217, 123,
Nemotcnica, 2, 31, 35, 37, 58, 65, argumentos del procedimiento
72, de promocin de 137, 58, 73,
78, 83, 84 81, 205
Programacin modular, 119, 123, 178 Empujar, 19, 85, 104, 105, 120, 121,
MOV, 2, 30, 33, 48, 53-55, 58, 75, 124, 125, 129, 132-134, 137, 140,
95, 100-102, 121, 124, 125, 129, 143, 205, 214
130, 132, 134, 137, 140, 143, 163,
204, 228, 231 R
MOVT, 75, 204
RAM, 9, 13, 18, 39, 188, 189, 195-
MPU, 4, 6, 217, 233
197
MRC, 86
RBIT, 72 205
MRRC, 86
registrarse
Seora, 24, 51, 75, 157, 170
APSR, 23, 24, 75, 76
MSR, 24, 51, 76, 170, 204
Registro base, 57, 60-62, 64
MUL, 67, 68, 177, 204
BasePri, 170, 171
MVN, 71, 204
BFAR, 154
CONTROL, 16, 18, 75, 76
N, O, P
DHCSR, 17
El desarrollo nativo, 173, 196 EPSR, 23, 24, 31, 75, 76, 155
NEG, 72, 90, 101, 102, 204 FaultMask, 170
anidados, 4, 15, 119, 120, 126, FAULTMASK, 18, 75, 76, 85
127, registros generales, 19, 23, 49, 51,
133, 136, 140, 146, 148, 166, 169 64
NMI, 23, 147-149, 151, 153, 158, 123, 136
161, 170, 217, 233 Registros de alta, 19
NOP, 20, 21, 26, 32, 40, 56, 66, 182, ICER, 160
204 El ISER, 160
Expresin numrica, 36 ISPER, 161, 166, 171
NVIC, 4, 15, 148, 150, 153, 154, 156, ISR, 23, 149
159, 160 a 162, 165-167, 169-171 Registra baja, 19
opcode, 18, 22, 50, 53, 157, 186, LR, 18, 20, 21, 26, 35, 51, 56, 78,
187 operando, 30, 32, 33, 39, 47, 52- 84, 85, 96, 104, 105, 119-121,
54, 124, 125, 129, 132, 134, 137,
58, 64, 68, 69, 187 140, 143, 155, 157, 168, 169,
El ORN, 52, 72, 204 177, 194, 202, 214, 217
ORR, 52, 72, 204, MSP (SP_Main), 19
214, 196, NVIC_dpi, 161, 162
superposicin NVIC_SHCSR, 154
PENDSV, 158
Perifrico, 4, 5, 7 a 10, 154, 160
245 Assembly Language Programming Index 245

NVIC_SHPR, 161, 162 Puntero, 18, 27, 51, 81, 116, 117,
PC, 18, 19, 21, 22, 54, 55, 57, 58, 120, 148, 149
59, 75, 78-85, 104, 105, 119, STC, 86
120, 155, 157, 167-169, 186, STM, 58, 82-85, 206
197, 202, 203, 207, 214 STMDB, 82, 84, 206
PRIMASK, 18, 75, 76, 85 STR, 47, 57, 58, 60, 81, 82, 121, 124,
R0 a R12, 18, 19, 49 125, 129, 132, 134, 137, 140, 143,
R13 o SP, 18, 19, 51, 148 206, 214, 231
R14, 18-20, 51 STRB, 58, 81, 101, 102, 137, 143,
R15, 18, 21, 51, 82, 149 163
UFSR, 153, 155, 156, 168 STRBT, 85
en la tabla de reubicacin, Std, 58, 84, 206
185-190 STREX, 85
Requerir8, 41 STRH, 58, 60, 81, 100, 137, 143,
Reset, 4, 10, 16, 27, 143, 147-151, 177, 214
153, 158, 160, 161, 165, 167, 170, STRSBT, 85
182, 185, 189, 192, 211, 212, 217, SUB, 52, 67, 69, 80, 130, 134, 137,
225, 231, 233 138, 140, 143, 206, 214
REV, 72, 73, 205 SVC, 86, 156-158, 161, 217, 233
REV16, 73, 205 SVCall, 156, 157, 217, 233
REVSH, 73, 205 SWI, 86
RN, 39, 49 Switch Case, 94-98
RO-datos, 191, 192, 194 SXTB, 74, 206
ROR, 52, 73, 74, 205 SXTH, 74, 206
Derrota, 41, 42 Smbolo, 21, 26, 27, 29, 30, 40-45, 48,
RRX, 52, 73 49, 64, 65, 112, 179, 180-182,
RSB, 52, 67, 69, 72 185-190, 197, 228-230
RW-zona de datos, 191 Tabla, 27, 43, 180, 181, 185-189,
197, 230
S Pila del sistema, 1, 2, 19, 27, 28, 41, 84,
85, 104, 114, 117, 120, 125, 126,
SBC, 52, 68, 80
133-136, 148, 157, 168, 175, 191,
SBFX, 73, 74, 205, 206
197, 225, 231
SDIV, 68, 214
SYSTICK, 212
SEV, 86
Simple ejecutable, 175, 194
SMLAL, 67, 68, 205
T, U
SMULL, 68, 205 Cola-encadenamiento, 169, 170
SSAT, 23, 52, 68, 205 TBB, 80, 95, 96, 207
Pila, 1, 18-20, 27, 40, 41, 51, 81, 83 TBH, 80, 95, 96, 207
85, 115 - 117, 120, 126-131, Eqt, 52, 77, 207
133 Modo de subproceso, 15, 16, 19, 148, 168,
134, 136, 137, 139, 140, 142-144, 169
148, 149, 157, 168, 169, 182, 191,
217, 225, 231, 233
246 Assembly Language Programming Index 246

Pulgar, 16, 17, 21, 23, 26, 31, 32, 49,


50, 52, 77, 155, 187, 191 W
TPUI, 6
Dbil, 150, 151, 176, 181-183, 217,
Trampa, 82, 153-156, 158, 159
225
TST, 52, 77, 93,
WFE, 86
207, 61 tabla tpica
WFI, 86
UBFX, 73, 74, 207
Rendimiento, 86
UDIV, 69, 177, 207
ZI- zona de datos, 192
UMLAL, 69, 207
UMULL, 69
Fallo de uso, 39, 153, 155, 167,
168,
217, 233
USAT, 23, 52, 69, 207
Pila de usuario, 40, 127-131, 133 y
136-
138, 140, 142, 145, 146
UXTB, 74, 207
UXTH, 74, 207
~Sto
rmR
G~
247 Assembly Language Programming Index 247