Diferencia entre revisiones de «Tablas en assembler (Codewarrior IDE)»

De Wikitronica
Saltar a: navegación, buscar
 
(No se muestran 23 ediciones intermedias de 2 usuarios)
Línea 1: Línea 1:
¿Qué es una tabla?
 
  
Una tabla en el lenguaje ensamblador, es un conjunto de datos colocados uno a uno en posiciones de memoria sucesivas para su posterior utilización en el programa. Normalmente no existe una relación directa  entre cada uno de los datos que conforman la tabla.
+
[[Categoría: EC2721 - Arquitectura del Computador 1]]
  
¿Cómo creamos una tabla?
+
[[Categoría:MC9S08QE128]]
  
    En primer lugar se debe localizar la dirección de memoria a partir de donde se iniciarán las definiciones de datos dentro de la tabla. Existe un gran número de direcciones que pueden ser utilizadas como referencia de inicio de la tabla, no obstante ciertas precauciones deben tomarse en  cuenta para no dañar la estructura del programa o bien para que la tabla puede crearse satisfactoriamente. Se debe procurar no establecer el inicio de la tabla en direcciones de memoria de uso frecuente, como por ejemplo en la “Direct Page”  ya que en esta zona suele trabajar la pila.
 
  
Véase el siguiente ejemplo:
+
En el siguiente artículo se abarcan brevemente los conceptos básicos para iniciarse en la implementación de tablas en lenguaje ensamblador, bajo el ambiente de desarrollo CODEWARRIOR IDE.
  
;**************************************************************
 
;*                          TABLA                            *
 
;**************************************************************
 
  
          ORG    $3000
+
=¿Qué es una tabla?=
  
         
 
  
Tabla:
+
Una tabla en el lenguaje ensamblador, es un conjunto de datos colocados uno a uno en posiciones de memoria sucesivas para su posterior utilización en el programa. Normalmente no existe una relación directa entre los datos que conforman la tabla.
  
          DC.B  'H'
 
  
          DC.B  'E'
+
=¿Cómo creamos una tabla?=
  
          DC.B 'L'
+
En primer lugar se debe localizar la dirección de memoria a partir de donde se iniciarán las definiciones de datos dentro de la tabla. Existe un gran número de direcciones que pueden ser utilizadas como referencia de inicio de la tabla, no obstante ciertas precauciones deben tomarse en cuenta para no dañar la estructura del programa o bien para que la tabla puede crearse satisfactoriamente. Se debe procurar no establecer el inicio de la tabla en direcciones de memoria de uso frecuente, como por ejemplo en la “Direct Page”  ya que en esta zona suele trabajar la pila.
  
          DC.B  'L'
 
  
          DC.B  'O'
+
'''Véase el siguiente ejemplo:'''
  
          DC.B  ' '
+
<syntaxhighlight lang="asm">
 +
;**************************************************************
 +
;*                          TABLA                            *
 +
;**************************************************************
  
          DC.B  'W'
+
ORG    $3000
  
          DC.B  'O'
+
Tabla:
  
          DC.B  'R'
+
DC.B  'H'
 +
DC.B  'E
 +
DC.B  'L'
 +
DC.B  'L'
 +
DC.B  'O'
 +
DC.B  ' '
 +
DC.B  'W'
 +
DC.B  'O'
 +
DC.B  'R'
 +
DC.B  'L'
 +
DC.B  'D'
 +
DC.B  0
 +
</syntaxhighlight>
  
          DC.B  'L'
 
  
          DC.B 'D'
+
Con la directiva ORG se establece que la dirección memoria $3000 (elegida de forma arbitraria) será el inicio de la tabla. Por otro lado con la directiva DC.B, se definen constantes de tamaño no mayor a 1 byte, en este caso caracteres.
  
          DC.B  0
+
'''PRECAUCIÓN:''' Al usar la directiva ORG procure mantener el orden descendente de las direcciones de memoria. En un programa común desarrollado en CODEWARRIOR IDE, las direcciones de memoria de menor denominación contienen las primeras líneas del código (definición de variables por ejemplo) mientras que las de mayor denominación deben contener las últimas líneas del mismo (Definición de los vectores de interrupción, otro ejemplo) Si un programa culmina en la dirección de memoria $FFF0 (nuevamente un ejemplo) y una tabla es definida posterior a esta pero iniciando en la posición $3000, la tabla no se creará correctamente en memoria.
  
    Con la directiva ORG se establece que la dirección de inicio de la tabla es $3000 (elegida de forma arbitraria) Por otro lado con la directiva DC.B, se definen constantes de tamaño no mayor a 1 byte, en este caso caracteres.
+
Ejemplo: ''' NO HACER ESTO'''
  
Otro formato:
 
  
 +
<syntaxhighlight lang="asm">
 
;**************************************************************
 
;**************************************************************
 
+
;*                 Vectores de interrupción                  *
;*                         TABLA                            *
+
 
+
 
;**************************************************************
 
;**************************************************************
  
Tabla:
+
            ORG  $FFF0
  
 +
            DC.W  TPM1Interrupt    ; Rutina de interrupción del TPM1
  
          DC.B  'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D',0
 
  
Otro ejemplo: Tabla de valores  “aleatorios”(base decimal)
 
  
;**************************************************************
 
 
;*                        TABLA                              *
 
  
 +
;**************************************************************
 +
;*                          TABLA                            *
 
;**************************************************************
 
;**************************************************************
  
            
+
           ORG    $3000
  
            ORG  ROMTabla
+
Tabla:
  
Tabla:         
+
DC.B  'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D',0
 +
</syntaxhighlight>
  
            DC.B  2,4,6,1,6,3,5,2,4,3
 
  
            DC.B  1,4,6,1,5,3,4,2,5,1
 
  
            DC.B  1,5,6,4,2,3,1,5,2,3
+
'''Otro formato:'''
 +
<syntaxhighlight lang="asm">
 +
;**************************************************************
 +
;*                          TABLA                            *
 +
;**************************************************************
  
            DC.B  6,3,2,5,6,3,2,5,4,1
+
ORG    $3000
  
            DC.B  4,5,1,2,3,6,5,2,3,6
+
Tabla:
  
            DC.B  1,3,6,4,2,5,6,3,2,5
+
DC.B  'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D',0
  
            DC.B  1,2,3,4,1,2,5,2,4,3
 
  
            DC.B  1,2,5,4,6,3,2,4,5,1
+
</syntaxhighlight>
 +
[[Archivo:memoria_look.png|400px|thumb|derecha|Vista en memoria de los datos en la tabla.]]
  
            DC.B  4,5,2,1,3,6,5,4,1,2
 
  
            DC.B 1,2,3,4,5,2,1,2,5,3
+
Vale la pena resaltar que para ambos casos, el carácter ‘H’ ocupa la posición de memoria $3000, el carácter ‘E’ la posición $3001, y así sucesivamente. Esto es debido a que cada carácter ocupa un byte en memoria.
  
            DC.B  6,3,6,3,4,1,2,4,5,4
 
  
            DC.B  4,4,4,2,5,4,6,2,1,6
 
  
            DC.B  1,2,3,4,5,6,4,5,2,1
 
  
            DC.B  1,2,4,5,2,2,1,2,2,5
+
'''Otro ejemplo: Tabla de valores “aleatorios” [1-6] (base decimal)'''
  
            DC.B  4,1,5,2,6,3,5,2,6,3
+
<syntaxhighlight lang="asm">
 +
;**************************************************************
 +
;*                          TABLA                            *
 +
;**************************************************************
  
            DC.B  1,4,2,5,3,5,2,5,2,4
+
ORG  ROMTabla
  
            DC.B  4,1,2,5,2,4,1,3,6,4
+
Tabla:
  
            DC.B  1,4,2,5,4,1,2,5,4,1
+
DC.B  2,4,6,1,6,3,5,2,4,3
 +
DC.B  1,4,6,1,5,3,4,2,5,1
 +
DC.B  1,5,6,4,2,3,1,5,2,3
 +
DC.B  6,3,2,5,6,3,2,5,4,1
 +
DC.B  4,5,1,2,3,6,5,2,3,6
 +
DC.B  1,3,6,4,2,5,6,3,2,5
 +
DC.B  1,2,3,4,1,2,5,2,4,3
 +
DC.B  1,2,5,4,6,3,2,4,5,1
 +
DC.B  4,5,2,1,3,6,5,4,1,2
 +
DC.B  1,2,3,4,5,2,1,2,5,3
 +
DC.B  6,3,6,3,4,1,2,4,5,4
 +
DC.B  4,4,4,2,5,4,6,2,1,6
 +
DC.B  1,2,3,4,5,6,4,5,2,1
 +
DC.B  1,2,4,5,2,2,1,2,2,5
 +
DC.B  4,1,5,2,6,3,5,2,6,3
 +
DC.B  1,4,2,5,3,5,2,5,2,4
 +
DC.B  4,1,2,5,2,4,1,3,6,4
 +
DC.B  1,4,2,5,4,1,2,5,4,1
 +
DC.B  4,5,2,3,6,5,4,1,2,5
 +
DC.B  1,2,4,5,2,3,6,5,2,1
 +
DC.B  1,2,4,5,3,6,2,5,4,1
 +
DC.B  4,2,5,2,3,6,2,2,4,1
 +
DC.B  1,4,2,3,6,4,1,2,5,2
 +
DC.B  2,1,4,2,5,6,3,6,5,1
 +
DC.B  1,2,3,4,5,2,1,4,5,2
 +
DC.B  6,5,4,3,2,1
 +
</syntaxhighlight>
  
            DC.B  4,5,2,3,6,5,4,1,2,5
+
==¿Cómo hacer en el caso de querer guardar valores de 2 bytes en una tabla?==
  
            DC.B  1,2,4,5,2,3,6,5,2,1
+
Recordemos que para definir una constante de 2 bytes es necesario utilizar la directiva "DC.W" y luego el valor en cuestión. Ahora bien, el orden en el cual son almacenados los datos en la mayoría de los microcontroladores de Freescale es con el formato "Big Endian". (Ver [[Little Endian y Big Endian]])
  
            DC.B  1,2,4,5,3,6,2,5,4,1
+
Para ejemplificar esto, tomaremos el caso de la inicialización de la interrupción del timer TPM1 (El principio es exactamente igual al de las tablas). Este es inicializado de la siguiente manera:
  
            DC.B  4,2,5,2,3,6,2,2,4,1
+
<syntaxhighlight lang="asm">
  
            DC.B  1,4,2,3,6,4,1,2,5,2
+
;**************************************************************
 +
;*                Vectores de interrupción                  *
 +
;**************************************************************
  
             DC.B  2,1,4,2,5,6,3,6,5,1
+
             ORG  $FFF0
  
             DC.B 1,2,3,4,5,2,1,4,5,2
+
             DC.W TPM1Interrupt    ; Rutina de interrupción del TPM1
  
            DC.B  6,5,4,3,2,1
 
  
+
</syntaxhighlight>
¿Cómo  acceder  al contenido de la tabla?
+
[[Archivo:Memory_look2.png|300px|thumb|derecha|Almacenamiento de datos tipo Big Endian]]
  
Véase el siguiente ejemplo:
 
  
Inicio_Lectura:
+
En FFF0 se guarda la dirección en la cual se encuentra la rutina de interrupción, por ejemplo, 26BE (recordemos que la dirección de dicha rutina depende de su ubicación dentro del código por lo que varía en cada programa) . El byte mas significativo (26) es guardado en la memoria baja (FFF0), y el menos significativo (BE) en la consecutiva mas alta (FFF1)
  
  
  
                                                    ;Se usa la dirección de Tabla como una constante
+
=¿Cómo  acceder  al contenido de la tabla?=
  
  
  
            LDHX  #Tabla                ;y se guarda en el registro H:X
+
'''Véase el siguiente ejemplo:'''
  
 +
<syntaxhighlight lang="asm">
 +
Inicio_Lectura:
 +
                            ;Se usa la dirección de Tabla como una constante
 +
LDHX  #Tabla                ;y se guarda en el registro H:X
  
 +
Lectura:
 +
MOV  ,X+,Caracter          ;Se mueve el contenido de la memoria indicada por H:X a la
 +
LDA  Caracter              ;variable "Caracter".
 +
CMP  #0                    ;Si Caracter vale 0, terminamos de recorrer la tabla y volvemos
 +
BEQ  Inicio_Lectura        ;a empezar.
 +
BRA  Lectura
 +
</syntaxhighlight>
  
Lectura:         
 
  
 +
En este programa la variable "Caracter" irá adquiriendo por cada iteración el valor de cada letra, según lo indique el registro H:X.
  
  
            MOV  ,X+,Caracter      ;Se mueve el contenido de la memoria indicada por H:X a la
 
  
 +
'''Forma alternativa:'''
  
 +
<syntaxhighlight lang="asm">
 +
Inicio_Lectura:
 +
CLRH                    ;Se limpia el registro H:X
 +
CLRX
  
            LDA  Caracter              ;variable "Caracter".
+
Lectura:
 
+
LDA  Tabla,X          ;Se mueve el contenido de la memoria indicada por H:X a la
 
+
STA  Caracter          ;variable "Caracter"`, por medio del acumulador
 
+
INCX
            CMP  #0                      ;Si Caracter vale 0, terminamos de recorrer la tabla y volvemos
+
CMP  #0               ;Si Caracter vale 0, terminamos de recorrer la tabla y volvemos
 
+
BEQ  Inicio_Lectura    ;a empezar.
 
+
BRA  Lectura
 
+
            BEQ  Inicio_Lectura    ;a empezar.
+
 
+
 
+
 
+
            BRA  Lectura
+
 
+
 
+
 
+
+
 
+
    En este programa la variable carácter irá adquiriendo por cada iteración el valor de cada letra, según lo indique el registro H:X. 
+
 
+
+
 
+
Forma alternativa:
+
 
+
Inicio_Lectura:                                 
+
 
+
 
+
 
+
            CLRH                    ;Se limpia el registro H:X
+
 
+
 
+
 
+
            CLRX
+
 
+
 
+
 
+
Lectura:         
+
 
+
 
+
 
+
            LDA  Tabla,X          ;Se mueve el contenido de la memoria indicada por H:X a la
+
 
+
 
+
 
+
            STA  Caracter          ;variable "Caracter"`, por medio del acumulador
+
 
+
 
+
 
+
            INCX
+
 
+
 
+
 
+
            CMP  #0                 ;Si Caracter vale 0, terminamos de recorrer la tabla y volvemos
+
 
+
 
+
 
+
            BEQ  Inicio_Lectura    ;a empezar.
+
 
+
  
  
            BRA  Lectura     
+
</syntaxhighlight>
  
--[[Usuario:JRodríguez|JRodríguez]] ([[Usuario discusión:JRodríguez|discusión]]) 14:48 26 mar 2013 (VET)JRodríguez
+
=Aplicaciones=
 +
En el siguiente enlace se encuentran un par de programas que implementan las tablas para realizar una determinada tarea:
 +
[[Ejemplo aplicaciones de Tablas en assembler]]

Revisión actual del 21:14 2 abr 2013


En el siguiente artículo se abarcan brevemente los conceptos básicos para iniciarse en la implementación de tablas en lenguaje ensamblador, bajo el ambiente de desarrollo CODEWARRIOR IDE.


¿Qué es una tabla?

Una tabla en el lenguaje ensamblador, es un conjunto de datos colocados uno a uno en posiciones de memoria sucesivas para su posterior utilización en el programa. Normalmente no existe una relación directa entre los datos que conforman la tabla.


¿Cómo creamos una tabla?

En primer lugar se debe localizar la dirección de memoria a partir de donde se iniciarán las definiciones de datos dentro de la tabla. Existe un gran número de direcciones que pueden ser utilizadas como referencia de inicio de la tabla, no obstante ciertas precauciones deben tomarse en cuenta para no dañar la estructura del programa o bien para que la tabla puede crearse satisfactoriamente. Se debe procurar no establecer el inicio de la tabla en direcciones de memoria de uso frecuente, como por ejemplo en la “Direct Page” ya que en esta zona suele trabajar la pila.


Véase el siguiente ejemplo:

;**************************************************************
;*                          TABLA                             *
;**************************************************************

ORG     $3000

Tabla:

DC.B  'H'
DC.B  'E
DC.B  'L'
DC.B  'L'
DC.B  'O'
DC.B  ' '
DC.B  'W'
DC.B  'O'
DC.B  'R'
DC.B  'L'
DC.B  'D'
DC.B   0


Con la directiva ORG se establece que la dirección memoria $3000 (elegida de forma arbitraria) será el inicio de la tabla. Por otro lado con la directiva DC.B, se definen constantes de tamaño no mayor a 1 byte, en este caso caracteres.

PRECAUCIÓN: Al usar la directiva ORG procure mantener el orden descendente de las direcciones de memoria. En un programa común desarrollado en CODEWARRIOR IDE, las direcciones de memoria de menor denominación contienen las primeras líneas del código (definición de variables por ejemplo) mientras que las de mayor denominación deben contener las últimas líneas del mismo (Definición de los vectores de interrupción, otro ejemplo) Si un programa culmina en la dirección de memoria $FFF0 (nuevamente un ejemplo) y una tabla es definida posterior a esta pero iniciando en la posición $3000, la tabla no se creará correctamente en memoria.

Ejemplo: NO HACER ESTO


;**************************************************************
;*                 Vectores de interrupción                   *
;**************************************************************

            ORG   $FFF0

            DC.W  TPM1Interrupt     ; Rutina de interrupción del TPM1




;**************************************************************
;*                          TABLA                             *
;**************************************************************

           ORG     $3000

Tabla:

DC.B  'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D',0


Otro formato:

;**************************************************************
;*                          TABLA                             *
;**************************************************************

ORG     $3000

Tabla:

DC.B  'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D',0
Vista en memoria de los datos en la tabla.


Vale la pena resaltar que para ambos casos, el carácter ‘H’ ocupa la posición de memoria $3000, el carácter ‘E’ la posición $3001, y así sucesivamente. Esto es debido a que cada carácter ocupa un byte en memoria.



Otro ejemplo: Tabla de valores “aleatorios” [1-6] (base decimal)

;**************************************************************
;*                          TABLA                             *
;**************************************************************

ORG   ROMTabla

Tabla:

DC.B  2,4,6,1,6,3,5,2,4,3
DC.B  1,4,6,1,5,3,4,2,5,1
DC.B  1,5,6,4,2,3,1,5,2,3
DC.B  6,3,2,5,6,3,2,5,4,1
DC.B  4,5,1,2,3,6,5,2,3,6
DC.B  1,3,6,4,2,5,6,3,2,5
DC.B  1,2,3,4,1,2,5,2,4,3
DC.B  1,2,5,4,6,3,2,4,5,1
DC.B  4,5,2,1,3,6,5,4,1,2
DC.B  1,2,3,4,5,2,1,2,5,3
DC.B  6,3,6,3,4,1,2,4,5,4
DC.B  4,4,4,2,5,4,6,2,1,6
DC.B  1,2,3,4,5,6,4,5,2,1
DC.B  1,2,4,5,2,2,1,2,2,5
DC.B  4,1,5,2,6,3,5,2,6,3
DC.B  1,4,2,5,3,5,2,5,2,4
DC.B  4,1,2,5,2,4,1,3,6,4
DC.B  1,4,2,5,4,1,2,5,4,1
DC.B  4,5,2,3,6,5,4,1,2,5
DC.B  1,2,4,5,2,3,6,5,2,1
DC.B  1,2,4,5,3,6,2,5,4,1
DC.B  4,2,5,2,3,6,2,2,4,1
DC.B  1,4,2,3,6,4,1,2,5,2
DC.B  2,1,4,2,5,6,3,6,5,1
DC.B  1,2,3,4,5,2,1,4,5,2
DC.B  6,5,4,3,2,1

¿Cómo hacer en el caso de querer guardar valores de 2 bytes en una tabla?

Recordemos que para definir una constante de 2 bytes es necesario utilizar la directiva "DC.W" y luego el valor en cuestión. Ahora bien, el orden en el cual son almacenados los datos en la mayoría de los microcontroladores de Freescale es con el formato "Big Endian". (Ver Little Endian y Big Endian)

Para ejemplificar esto, tomaremos el caso de la inicialización de la interrupción del timer TPM1 (El principio es exactamente igual al de las tablas). Este es inicializado de la siguiente manera:

;**************************************************************
;*                 Vectores de interrupción                   *
;**************************************************************

            ORG   $FFF0

            DC.W  TPM1Interrupt     ; Rutina de interrupción del TPM1
Almacenamiento de datos tipo Big Endian


En FFF0 se guarda la dirección en la cual se encuentra la rutina de interrupción, por ejemplo, 26BE (recordemos que la dirección de dicha rutina depende de su ubicación dentro del código por lo que varía en cada programa) . El byte mas significativo (26) es guardado en la memoria baja (FFF0), y el menos significativo (BE) en la consecutiva mas alta (FFF1)


¿Cómo acceder al contenido de la tabla?

Véase el siguiente ejemplo:

Inicio_Lectura:
                             ;Se usa la dirección de Tabla como una constante
LDHX  #Tabla                 ;y se guarda en el registro H:X

Lectura:
MOV   ,X+,Caracter           ;Se mueve el contenido de la memoria indicada por H:X a la
LDA   Caracter               ;variable "Caracter".
CMP   #0                     ;Si Caracter vale 0, terminamos de recorrer la tabla y volvemos
BEQ   Inicio_Lectura         ;a empezar.
BRA   Lectura


En este programa la variable "Caracter" irá adquiriendo por cada iteración el valor de cada letra, según lo indique el registro H:X.


Forma alternativa:

Inicio_Lectura:
CLRH                    ;Se limpia el registro H:X
CLRX

Lectura:
LDA   Tabla,X           ;Se mueve el contenido de la memoria indicada por H:X a la
STA   Caracter          ;variable "Caracter"`, por medio del acumulador
INCX
CMP   #0                ;Si Caracter vale 0, terminamos de recorrer la tabla y volvemos
BEQ   Inicio_Lectura    ;a empezar.
BRA   Lectura

Aplicaciones

En el siguiente enlace se encuentran un par de programas que implementan las tablas para realizar una determinada tarea: Ejemplo aplicaciones de Tablas en assembler

Contributors

Aromero, JRodríguez