Autor Tema: Duda y aclaración de uso de instrucciones.  (Leído 1619 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Fer_TACA

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4036
Duda y aclaración de uso de instrucciones.
« en: 20 de Enero de 2020, 18:36:50 »
Dispongo de un programa en ASM y estoy tratando de ver cual es el funcionamiento del mismo, pero me encuentro con unas instrucciones que no entiendo muy bien cuales su significado y funcionamiento. Estas son las siguientes:

MOVLW   -D'6'. Comprendo que se carga el acumulador con el valor del literal, pero lo del signo " -" delante del tipo de literal es la rimera vez que lo veo.

Table   ADDWF   PCL,F

Tbase   equ   $
Car0           equ   $-Tbase
CarO           equ   $-Tbase

           RETLW   B'00001110'   ; ....***.
           RETLW   B'00010001'   ; ...*...*


En este trozo de código, en rojo me pierdo. Sobre todo con el:  equ   $-Tbase
Table y Tbase son etiquetas

BlkLns   ADDLW   -1
BlkLns es una etiqueta, pero aquì ya si me pierdo del todo al ver el "-1"

Alguien que domine el ASM, me podría aclarar cual es significado de cada uno de ellos.

F.
« Última modificación: 20 de Enero de 2020, 18:39:16 por Fer_TACA »
Todos los días se aprende algo nuevo.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Duda y aclaración de uso de instrucciones.
« Respuesta #1 en: 20 de Enero de 2020, 19:32:43 »
Te respondo...

El D'6' es obviamente el numero 6 decimal, como esa instruccion posee un opcode de 8 bits entonces es: 0000 0110 , un -6 es el complemento a 2 de 6, es decir 1111 1010  (not + 1)

Respecto al operador $ es la direccion donde se ejecuta esa instruccion... Uno de los usos que le das es en los GOTO por ejemplo. Si quiero hacer un salto de instrucciones hacia atras por ejemplo y tengo 2 instrucciones de 1 un lugar cada uno, entonces haria:

GOTO $-2

Es decir la direccion donde esta el GOTO restandole 2, ese es el valor binario que va a tener.


PD:

El poner D'6' o 6 es lo mismo, ya que es lo mismo en el sistema hexadecimal (que esta por default) que en el decimal,  distinto seria 10 y d'10', todo depende de como tenga seteado el radix
Tbase tiene la direccion del primero valor de la tabla. Luego los demas es la diferencia entre las dos direcciones, imagino que para saber cuanto se extiende la tabla, sin necesidad de tener un valor que indique la cantidad.

Desconectado Fer_TACA

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4036
Re:Duda y aclaración de uso de instrucciones.
« Respuesta #2 en: 21 de Enero de 2020, 07:28:59 »
Gracias por la repuesta KILLERJC.

Lo del complemento a 2 del decimal lo entiendo perfectamente. Es la primera vez que lo veo, ¿y no seria mas fácil el haber puesto directamente su valor en decimal, es decir 250?
Pero lo que no termino de entender es por que es distinto donde dices:


......................,  distinto seria 10 y d'10', todo depende de como tenga seteado el radix


Luego el ADDLW   -1, lo que realiza es la suma del acumulador con el literal complemento a 2 de 1.

Con respecto al resto, según tus indicaciones y en concreto con las lineas expuestas entiendo que si:
Tbase equ $ es la primera dirección de la tabla, en la siguiente instrucción Car0 equ$-Tbase seria la primera dirección de la tabla ya que si se realiza la resta entre la dirección de Car0 y Tbase, al estar contiguas pues el resultado seria 1. Luego para CarO seria la segunda posición de la tabla y así sucesivamente.

espero estar en lo cierto, mi ASM ya está bastante oxidado.

F.
« Última modificación: 21 de Enero de 2020, 07:46:56 por Fer_TACA »
Todos los días se aprende algo nuevo.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Duda y aclaración de uso de instrucciones.
« Respuesta #3 en: 21 de Enero de 2020, 10:36:27 »
Algunos lo usan directamente sin saberlo y otros ni lo usan... Pero al comienzo que suelen poner LIST=P...... Pueden poner tambien RADIX=  DEC, HEX, etc...

Esto le dice al compilador que espera que todos los numeros sean decimales o hexadecimales. Por ejemplo

Usando RADIX = HEX  (que es el que viene por default si no lo escribis) la instruccion MOVLW 10 pondria en W el numero 0x10 o 16 decimal.
Si usas RADIX = DEC la instruccion MOVLW 10 pondria el numero 0xA  o 10 decimal en W.

Si necesitas usar otro sistema usas las denominaciones que ves ahi, si por ejemplo esta en RADIX HEX y queres escribir un decimal, lo podes hacer haciendo .10 o d'10'

¿El porque poner un numero negativo te preguntaras? Por que es mas comodo. Tiene mas sentido. Supongamos el ADDLW -1 el podrias pensar que le esta restando 1, o que le esta sumando 0xFF, como esta limitado a 8 bits, esto queda en el mismo resultado.

Ejemplo : 8d  = 0000 1000
Si le sumo el -1, me quedaria:
0000 1000
1111 1111
------------
0000 0111  = 7d

Citar
Con respecto al resto, según tus indicaciones y en concreto con las lineas expuestas entiendo que si:
Tbase equ $ es la primera dirección de la tabla, en la siguiente instrucción Car0 equ$-Tbase seria la primera dirección de la tabla ya que si se realiza la resta entre la dirección de Car0 y Tbase, al estar contiguas pues el resultado seria 1. Luego para CarO seria la segunda posición de la tabla y así sucesivamente.

Es importante entender que es una etiqueta... el mejor ejemplo lo tenes aca:

Código: ASM
  1. BlkLns   ADDLW   -1

La etiquetas no ocupan lugar en memoria, solo lo hace la instruccion ADDLW, ¿entonces que es la etiqueta? Es simplemente un numero, que es la dirección de memoria donde se encuentra la instruccion ADDLW por eso cuando haces:

Código: ASM
  1. GOTO BlkLns

Luego el compilador lo transforma en algo asi:

Código: ASM
  1. GOTO 0x1234

Entonces... una etiqueta es únicamente un numero.

Ahora vamos con un ejemplo:

Código: ASM
  1. ORG 0x1000
  2. Table   ADDWF   PCL,F
  3. Tbase   equ   $
  4. Car0           equ   $-Tbase
  5. CarO           equ   $-Tbase
  6.            RETLW   B'00001110'   ; 1
  7.            RETLW   B'00001110'   ; 2
  8.            RETLW   B'00001110'   ; 3
  9.            RETLW   B'00001110'   ; 4

Por simplicidad agregue un ORG para que sea mas sencillo de entender.
Tbase es igual a $, es decir el primer RETLW, por lo que el $ vale 0x1001 = Tbase

Los EQU no son instrucciones por lo tanto no poseen memoria, y el $ no avanza, retiro lo que dije antes por que imagine otra cosa. Pero asi como esta el codigo parace que Car0 y CarO es 0. Me equivoque pensando que eran otras etiquetas, Es 0 porque el $ es 0x1001, y Tbase vale lo mismo, asi que la resta de ambos es 0.

A lo que me referia antes es que te permite hacer algo asi:

Código: ASM
  1. ORG 0x1000
  2. Table   ADDWF   PCL,F
  3. Tbase   equ   $
  4. Car0           equ   Tbas - $
  5. CarO           equ   Tcas - $
  6.            RETLW   B'00001110'   ; 1
  7.            RETLW   B'00001110'   ; 2
  8.            RETLW   B'00001110'   ; 3
  9. Tbas    RETLW   B'00001110'   ; 4
  10.            RETLW   B'00001110'   ; 5
  11.            RETLW   B'00001110'   ; 6
  12. Tcas     RETLW   B'00001110'   ; 7
  13.            RETLW   B'00001110'   ; 8

Si el codigo es asi , esto te permite tener los siguientes valores:
Tbase = 0x1001
Car0 = 3  ( de 0x1004 - 0x1001)
CarO = 6  ( de 0x1007 - 0x1001)
« Última modificación: 21 de Enero de 2020, 10:39:07 por KILLERJC »

Desconectado Fer_TACA

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4036
Re:Duda y aclaración de uso de instrucciones.
« Respuesta #4 en: 21 de Enero de 2020, 14:48:14 »
Gracias por la aclaracion KILLERJC

Lo de los complementos y los literales lo entiendo perfectamnete. Ahora voy a ver lo de las tablas, a ver si lo termino e comprender, aunque lo siguiente no lo termino de comprender:
Si el codigo es asi , esto te permite tener los siguientes valores:

Tbase = 0x1001. Esto si lo comprendo por que es la siguiente posicion al ORG0x1000.
Car0 = 3  ( de 0x1004 - 0x1001)
CarO = 6  ( de 0x1007 - 0x1001)

Pero en los pasos siguientes no se donde salen el 0x1004 y el 0x1007. Entiendo que el 1004 es la posición  donde se encuentra el Car0 y al restarle el 1001 que da como resultado 3 y seria el lugar donde se buscaría en la tabla el carácter Car0.
Ahora bien con el CarO ya no veo donde sale, pues siguiendo con mi deducción sería 0x1005-0x1001=4 y si se correspondería con la posición de regreso a la tabla para el valor CarO.
En este caso al ser posiciones seguidas y no haber otras instrucciones de por medio, el resultado es contiguo. Otra cosa es si la tabla es muy grande ya el resultado de la resta seria distinto.

F.
Todos los días se aprende algo nuevo.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Duda y aclaración de uso de instrucciones.
« Respuesta #5 en: 21 de Enero de 2020, 15:22:20 »
Aunque lo siguiente no lo termino de comprender:
Si el codigo es asi , esto te permite tener los siguientes valores:

Tbase = 0x1001. Esto si lo comprendo por que es la siguiente posicion al ORG0x1000.
Car0 = 3  ( de 0x1004 - 0x1001)
CarO = 6  ( de 0x1007 - 0x1001)

Pero en los pasos siguientes no se donde salen el 0x1004 y el 0x1007. Entiendo que el 1004 es la posición  donde se encuentra el Car0 y al restarle el 1001 que da como resultado 3 y seria el lugar donde se buscaría en la tabla el carácter Car0.
Ahora bien con el CarO ya no veo donde sale, pues siguiendo con mi deducción sería 0x1005-0x1001=4 y si se correspondería con la posición de regreso a la tabla para el valor CarO.
F.

Yo en el codigo de ejemplo que te di, puse unos numeros, esos numeros son el ultimo nibble de las direcciones,, explicitamente usando las direccion completas quedaria asi:

Código: ASM
  1. ORG 0x1000
  2. Table   ADDWF   PCL,F           ; 0x1000
  3. Tbase   equ   $
  4. Car0           equ   Tbas - $
  5. CarO           equ   Tcas - $
  6.            RETLW   B'00001110'   ; 0x1001 (Los RETLW ocupan una sola posicion de memoria)
  7.            RETLW   B'00001110'   ; 0x1002
  8.            RETLW   B'00001110'   ; 0x1003
  9. Tbas    RETLW   B'00001110'   ; 0x1004
  10.            RETLW   B'00001110'   ; 0x1005
  11.            RETLW   B'00001110'   ; 0x1006
  12. Tcas     RETLW   B'00001110'   ; 0x1007
  13.            RETLW   B'00001110'   ; 0x1008

Observa donde esta ubicado la etiqueta Tbas, es sobre el RETLW que esta ubicado en 0x1004, de ahi sale el 0x1004. Y lo mismo para el otro.
Aclaro que el codigo anterior y el que voy a poner son los mismo

Código: ASM
  1. ORG 0x1000
  2. Table  
  3.            ADDWF   PCL,F           ; 0x1000
  4. Tbase   equ   $
  5. Car0           equ   Tbas - $
  6. CarO           equ   Tcas - $
  7.            RETLW   B'00001110'   ; 0x1001 (Los RETLW ocupan una sola posicion de memoria)
  8.            RETLW   B'00001110'   ; 0x1002
  9.            RETLW   B'00001110'   ; 0x1003
  10. Tbas    
  11.            RETLW   B'00001110'   ; 0x1004
  12.            RETLW   B'00001110'   ; 0x1005
  13.            RETLW   B'00001110'   ; 0x1006
  14. Tcas    
  15.            RETLW   B'00001110'   ; 0x1007
  16.            RETLW   B'00001110'   ; 0x1008

Aca podes observar un poco mejor que las etiquetas no ocupan espacio en memoria... De todas formas las etiqueta Tbas tiene el valor 0x1004 y la Tcas 0x1007.


Citar
En este caso al ser posiciones seguidas y no haber otras instrucciones de por medio, el resultado es contiguo. Otra cosa es si la tabla es muy grande ya el resultado de la resta seria distinto.

De no haber instrucciones por medio, el operador $ no avanza, por lo tanto sigue teniendo el mismo valor, que es el caso de tu programa.
Si la tabla es muy grande el resultado va a depender de donde estén ubicadas las etiquetas.
« Última modificación: 21 de Enero de 2020, 15:24:22 por KILLERJC »

Desconectado Fer_TACA

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4036
Re:Duda y aclaración de uso de instrucciones.
« Respuesta #6 en: 21 de Enero de 2020, 15:51:28 »
Gracias de nuevo.

Ahora si lo acabo de entender. Mi equivocacion estaba en que las posiciones las empezaba a contar desde las etiquetas donde se encuentran los equ $.

F.
Todos los días se aprende algo nuevo.


 

anything