Paso 4: directivas de ensamblador .org
Ya sé lo que las directivas de ensamblador .nolist, .list, .include y .def de nuestros tutoriales anteriores, así que en primer lugar echemos un vistazo en las 4 líneas de código que vienen después de:
.org 0x0000 jmp Reset .org 0x0020 jmp overflow_handler
La instrucción org indica el ensamblador donde en "Memoria de programa" para poner la siguiente instrucción. Como se ejecuta el programa, el "contador de programa" (abreviados como PC) contiene la dirección de la línea actual de ejecución. Así que en este caso cuando el PC está en 0 x 0000 verá el comando "jmp Reset" que residen en esa localización de memoria. La razón por la que queremos poner jmp Reset en ese lugar es porque cuando se inicia el programa, o se resetea el chip, la PC inicia ejecución de código en este punto. Por lo tanto, como podemos ver, nos hemos sólo lo inmediatamente "saltar" a la sección etiquetada "Reset". ¿Por qué hacemos? Esto significa que las dos últimas líneas arriba sólo se se saltan encima. ¿Por qué?
Bueno eso es donde las cosas se ponen interesantes. Ahora vas a tener que abrir un visor de pdf con la hoja de datos completa de ATmega328p que señalé en la primera página de este tutorial (por qué es tema 4 en el "debe" sección). Si la pantalla es demasiado pequeña, o tienes demasiados windows abrir ya (como es el caso conmigo) podía hacer lo que hacen y ponga en un e-Reader o tu teléfono Android. Va a utilizarlo todo el tiempo si usted planea escribir código ensamblador. Lo cool es que todos microcontollers se organizan en formas muy similares así que cuando te acostumbras a leer hojas de datos y codificación de ellos que usted encontrará casi trivial de hacer lo mismo para un microcontrolador diferentes. Así que estamos realmente aprender a usar microcontroladores todos en un sentido y no sólo el atmega328p.
Bueno, vuelta a la página 18 en la hoja de datos y echar un vistazo en la figura 8-2.
Se trata de cómo se configura la memoria del programa en el microcontrolador. Se puede ver que comienza con la dirección 0 x 0000 y se separa en dos secciones; una sección de aplicación flash y una sección de flash de arranque. Si hace referencia brevemente a página 277 tabla 27-14 se verá que la sección flash aplicación toma las ubicaciones desde 0 x 0000 a 0x37FF y la sección de flash de arranque toma los lugares restantes de 0x3800 a 0x3FFF.
Ejercicio 1: ¿Cuántos lugares están ahí en la memoria del programa? Es decir convertir 3FFF en decimales y añadir 1 ya empezamos a contar en 0. Ya que cada posición de memoria es de 16 bits (o 2 bytes) ancho ¿cuál es el número total de bytes de memoria? Ahora convertir esto en kilobytes, recordar que hay 2 ^ 10 = 1024 bytes en un kilobyte. La sección de flash de arranque va desde 0x3800 hasta 0x37FF, ¿cuántos kilobytes es esto? ¿Cuántos kilobytes de memoria siguen siendo para que nosotros utilizar para almacenar nuestro programa? En otras palabras, ¿qué tan grande nuestro programa se puede? ¿Por último, el número de líneas de código podemos tener?
Bien, ahora que sabemos todo sobre la organización de la memoria de programa flash, vamos a continuar con nuestro debate de las declaraciones de .org. Vemos que la primera localización de memoria 0 x 0000 contiene nuestra instrucción para ir a nuestra sección hemos etiquetado Reset. Ahora vemos lo que hace la declaración ".org 0x0020". Se dice que queremos que la instrucción en la línea siguiente a colocarse en posición de memoria 0x0020. La instrucción que hemos colocado hay un salto a una sección en el código que nos hemos "overflow_handler"... ahora ¿por qué diablos le exigimos que este salto colocarse en posición de memoria 0x0020? Para averiguar, consultar página 65 en la hoja de datos y echa un vistazo a la tabla 12-6.
Tabla 12-6 es una tabla de "Restablecer y vectores de la interrupción" y le muestra exactamente donde lo PC van cuando recibe una "interrupción". Por ejemplo, si nos fijamos en el número de vectores 1. La "fuente" de la interrupción es "RESET" que se define como "Sistema Pin externo, Power-on Reset, Brown-out Reset y Watchdog reset" lo que significa, si cualquiera de esas cosas sucede que nuestro microcontrolador, el PC empezará a ejecutar nuestro programa en lugar de la memoria de programa 0 x 0000. ¿Qué pasa con nuestra directiva .org entonces? Bueno, colocamos un comando en lugar de la memoria 0x0020 y si mira hacia abajo de la tabla verás que si ocurre un desbordamiento de Timer/Counter0 (procedente de TIMER0 OVF) ejecutará todo lo que está en la ubicación 0x0020. Así que cuando eso sucede, la PC se salta al lugar nos con la etiqueta "overflow_handler". Cool ¿verdad? Verás en un minuto por qué hicimos esto, pero primero vamos a terminar este paso del tutorial con un aparte.
Si queremos hacer nuestro código más limpio y ordenado debemos realmente reemplazar las 4 líneas que actualmente estamos debatiendo con lo siguiente (pág. 66):
.org 0x0000 rjmp Reset ; PC = 0x0000 reti ; PC = 0x0002 reti ; PC = 0x0004 reti ; PC = 0x0006 reti ; PC = 0x0008 reti ; PC = 0x000A ... reti ; PC = 0x001E jmp overflow_handler : PC = 0x0020 reti : PC = 0x0022 ... reti ; PC = 0x0030 reti ; PC = 0x0032
Modo que si ocurre una interrupción dada él solo "reti" que significa "retorno de interrupción" y nada sucede. Pero si nunca "permitimos" estas interrupciones distintas, entonces no se utilizarán y podemos poner el código del programa en estos puntos. En nuestro programa actual de "blink.asm" sólo vamos a habilitar la interrupción de desbordamiento del timer0 (y, por supuesto, la interrupción de reset que está siempre activada) y así no molestará a los otros.
¿Cómo nos "habilita" la interrupción de desbordamiento del timer0 entonces? ... es el tema de nuestro próximo paso en este tutorial.