Autor Tema: Comprobando funcionamiento (ASM basico)  (Leído 2993 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado fartet

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 145
Comprobando funcionamiento (ASM basico)
« en: 10 de Febrero de 2007, 15:39:20 »
Hilo dedicado a programitas de comprobación de supuestos y aclaraciones al respecto
__________________________________________________________________________________________________
1º Supuesto, al salvar el registro STATUS y recuperarlo mediante instrucciones tipo MOV se corrompe el bit Z.

Programa usado en el simulador:

;Comprobando "guardar y recuperar STATUS, efecto sobre Z"
;Visualizar los registros: W, 0x03(STATUS), 0x0C(RSTA_1), 0x0E(CSTAZ_1),
;0x0D(RSTA_0), 0x0F(CSTAZ_0). Ejecutar paso a paso al simular.
;-------------------------------------------------------------------------------
        LIST    P=16F84
STA         EQU     0x03      ;STATUS
RSTAZ_1 EQU     0x0C      ;salva STATUS para Z=1
RSTAZ_0 EQU     0x0D      ;salva STATUS para Z=0
CSTAZ_1 EQU   0x0E      ;copia STATUS restaurado para Z=1
CSTAZ_0 EQU   0x0F      ;copia STATUS restaurado para Z=0
        ORG     0x000
;-------------------------------------------------------------------------------
        clrf    RSTAZ_1      
        clrf    RSTAZ_0      
   clrf   CSTAZ_1
   clrf   CSTAZ_0
;-------------------------------------------------------------------------------
;Salvando valores de STATUS para Z=1 y para Z=0
        clrw         ;(0->W)->(Z=1)
        movf    STA,0      ;Cargo valor de STATUS con Z=1 ...
        movwf   RSTAZ_1      ;... y lo salvo en RGA,lo que provoca Z=0
   nop         ;(por comodidad) Comprobar en RSTAZ_1 si Z=1
        movf    STA,0      ;Cargo valor de STATUS con Z=0 ...
        movwf   RSTAZ_0      ;... y lo salvo en RGB
;-------------------------------------------------------------------------------
;Comprobando "recuperar STATUS y efecto sobre Z"
   movf   RSTAZ_0,0   ;Cargamos un valor de STATUS guardado con Z=0...
   movwf   STA      ;... y lo reponemos a STATUS...
   movf   STA,0      ;... lo recargamos desde STATUS y ...
   movwf   CSTAZ_0      ;... guardamos copia en CSTAZ_0 ¿es = a RSTAZ_0?
   nop         ;(para mi comodidad)
   movf   RSTAZ_1,0   ;Cargamos un valor de STATUS guardado con Z=1...
   movwf   STA      ;... y lo reponemos a STATUS
   movf   STA,0      ;... lo recargamos desde STATUS y ...
   movwf   CSTAZ_1      ;... guardamos copia en CSTAZ_1 ¿es = a RSTAZ_1?
;-------------------------------------------------------------------------------
   END
___________________________________________________________________________________________________
Resultados de la simulación:
       (RTAZ_1)=00011111
       (CTAZ_1)=00011111
       (RTAZ_0)=00011011
       (CTAZ_0)=00011011
A pesar de las múltiples instruciones MOV los valores salvados y recuperados parecen correctos ¿Donde está el fallo?
____________________________________________________________________________________________________
P.D. Si los moderadores consideran que este hilo está de más y lo borran, o que debe unirse a otro preexistente y lo trasladan, no me sentire molesto por ello.
« Última modificación: 10 de Febrero de 2007, 15:40:51 por fartet »

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Comprobando funcionamiento (ASM basico)
« Respuesta #1 en: 10 de Febrero de 2007, 19:56:08 »
Hola fartet.

Si bien creo comprender tu intencion, no comprendo por qué utilizas dos registros para guardar temporalmente el valor del registro STATUS. Por lo que veo uno de ellos posee Z en alto y el otro Z en bajo, pero no es necesario. Solo hace falta 1 registro para salvar el STATUS.

Remontemonos a la pregunta original que ha sido mencionada en otro hilo: ¿Por que utilizan SWAPF en lugar de MOVF para guardar ciertos registros especiales?

Bien.
Ahora veamos por que tu programa parece funcionar.
Tu programa se comporta siempre de manera identica. Ese es el primer error. Lo primero que haces es:
clrw

Lo que provoca que siempre Z va a valer 1 luego de eso. Esto no es lo que se pretende lograr(ni es correcto) a la hora  de guardar los registros especiales dentro de la rutina de interrupcion.

Te armo un programa donde podes apreciar el problema de los movf:


Código: ASM
  1. org  0x0000
  2.             goto INICIO
  3.    
  4.             org  0x0004
  5.             movwf  W_TEMP
  6.             movf     STATUS,W
  7.             movwf  STATUS_TEMP
  8.             nop
  9.             nop
  10.             movf    STATUS_TEMP,W
  11.             movwf  STATUS
  12.             movf     W_TEMP,W
  13.             return
  14. INICIO
  15.            movlw 0x10
  16.            clrf    Registro             ;Registro=0
  17.            movf Registro,f           ;Z=1
  18.            call    0x0004              ;Simular interrupcion
  19.            goto  INICIO

Veamos como afecta ese codigo a las variables:

al momento de ejecutarse la instruccion call 0x0004 el valor de:
Registro = 0
W = 0x10
STATUS = b'XXXXX1XX'     es decir, Z= 1 debido al movf Registro,F

Ahora veamos como guarda los registros calve:

movwf W_TEMP

W_TEMP = 0x10 = W  esto esta OK.

Ahora se ejecuta:

movf     STATUS,W
STATUS recordemos que valia antes de esta instruccion: b'XXXXX1XX'

al ejecutarse movf STATUS,W sucede que STATUS es distinto de cero(el bit Z vale 1, por lo que es suficiente para que STATUS sea distinto a cero), por lo que Z se pone en bajo entonces ahora:

W = b'XXXXX0XX'

y continua con:

movwf STATUS_TEMP

por lo que STATUS_TEMP = b'XXXXX0XX'

Y alli esta el error.

STATUS ingresó a la rutina de interrupcion valiendo b'XXXXX1XX' y STATUS_TEMP deberia contener el mismo valor para poder luego reestablecerlo, pero no lo contiene. STATUS_TEMP contiene b'XXXXX0XX'

Alli esta el error de utilizar la movf que afecta el flaf Z en lugar de la SWAPF.

Saludos.

"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado fartet

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 145
Re: Comprobando funcionamiento (ASM basico)
« Respuesta #2 en: 10 de Febrero de 2007, 21:09:14 »
Este programita tiene por unica misión ver si el valor de Z se modifica en el proceso de salvar en un registro auxiliar el STATUS y luego recuperarlo, por ello la prueba debe de hacerse tanto para Z=0 como para Z=1

El proceso que sigo es simple, despues de clrw queda Z=1, y así se carga en W y se salva, solo que la instrucción que lo copia en W provoca que en el STATUS Z pase a valer 0, lo que salvo y guardo despues.

No debería haber error puesto que es la misma instruccion la que copia STATUS (con Z=0) en W y la que modifica al bit Z (pasandolo a 0), y no hay error porque Z se modifica como consecuencia de haber copiado, no previo a haber copiado, por tanto el valor que se escribio en W es el original y no la consecuencia.(Z depende del resultado de la operación, pero no modifica la operacion).

Con esa premisa guardo en dos ficheros ambos valores del STATUS, uno con Z=0 y otro con Z=1, (de hecho puede comprobarse que se guardan ambos correctamente), luego el proceso de salvar el registro STATUS mediante instrucciones de tipo MOV de cara a una rutina cualquiera no debe presentar ningun problema, sea cual sea el valor del bit Z.

En la siguiente parte del programa se regresan a STATUS ambos valores que habiamos salvado, y de inmediato se vuelve a sacar de STATUS copia en otros ficheros (puesto que el STATUS puede seguir cambiando y quiero comparar al final), el resultado es que la recuperacion del valor guardado de STATUS tanto cuando Z=0 como cuando Z=1 se efecúa con MOV y tampoco hay problema (los registros duplicados mantienen la información de los originales).

(*) El tema es que en la bibliografia se repite hasta la saciedad que no se pueden utilizar MOV para salvar y recuperar posteriormente el valor del STATUS porque el bit Z se corrompe, y en estas pruebas se demuestra que no ocurre así. Entonces ¿donde está el truco?, a mi lo único que se me ocurre es que mientras en el simulador se ejecuta primero la operación y su resultado es el que queda reflejado en Z, que en el chip fisico contra toda lógica ocurra al contrario, ya lo comprobaré en cuando tenga ocasión.
« Última modificación: 10 de Febrero de 2007, 21:38:08 por fartet »

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Comprobando funcionamiento (ASM basico)
« Respuesta #3 en: 10 de Febrero de 2007, 21:33:18 »
Realmente, sere medio bobo, pero no logro comprender tu objetivo(creo que es sencillamente refutar lo que dice esa bibliografia a la que te referis).

En caso de que funcione, y guarde en un registro para Z= 0 y en otro para Z=1 tenes dos registros, y en tal caso al salir del servicio de interrupcion, cual seleccionarias de ambos para guardar en STATUS?

Si a mi pregunta vas a responder que utilizas ambos registros solamente para demostrar ambos casos (para Z= 0 y para Z=1) me parece que lo correcto seria que armes un unico algoritmo que sirva para ambos casos(Z=0 y Z=1) tal cual lo hace el algoritmo que utiliza SWAPF.

Si realmente queres demostrar que se podria aplicar tu programa para reemplazar el mas comun utilizado(el que utiliza SWAPF) primero deberias lograr guardar W,STATUS y PCLATH y recuperarlos tal cual ingresaron a la rutina de interrupcion.

Seguramente hay formas de utilizar MOVF en lugar de SWAPF. Hay millones de maneras de hacer lo mismo en programacion.
Hay una frase que dice: "todos los caminos conducen a Roma".
Si queres tomar el camino largo y complicado, podes hacerlo usando instrucciones MOVF.
Si queres el camino corto y simple, utiliza las SWAPF.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado fartet

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 145
Re: Comprobando funcionamiento (ASM basico)
« Respuesta #4 en: 10 de Febrero de 2007, 22:12:41 »
Es el problema de dialogo escrito, a veces no espreso adecuadamente lo que quiero decir.

Para guardar STATUS solo utilizare un unico fichero, en el programa previo use cuatro para comprobar con una única ejecución todas las posibilidades que se me ocurrieron (ambos valores para Z al guardarlos y ambos al recuperarlos).

El objetivo del programa era simplemete comprobar si es cierta una aseveración de la bibliografia habitual, que Z se corrompe si se guarda y recupera con instruciones MOV, no entro en si es el metodo mejor o no, simplemente en si es cierto o falso.

PD1 Probaré a guardar los registros que comentas. Me gusta comprobar las cosas que puedan serlo antes de aceptarlas como dogma. Te agradezco la atención que me has prestado.

Desconectado fartet

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 145
Re: Comprobando funcionamiento (ASM basico)
« Respuesta #5 en: 12 de Febrero de 2007, 18:33:05 »
Queda claro que si se quiere salvar solo STATUS y recuperarlo puede hacerse usando instrucciones MOV

Pero como aporta BrunoF si además de STATUS hay que salvar otros registros importantes es cuando surgen problemas.

Salvar varios registros, STATUS y W entre ellos
      1º salvar W (lógico puesto que W se usará como puente para salvar los siguientes).
      2º salvar STATUS
      3º salvar resto de registros....
Recuperarlos en orden inverso (W será el último en recuperarse por la misma razón de antes)
      1º recuperar registros menos STATUS y W
      2º recuperar STATUS
      3º recuperar W (y es aqui con MOVF F,D  cuando si que se afecta el bit Z de STATUS)

Conclusiones: si se salva solo STATUS ambos métodos són validos, pero lo más usual, al menos con interrupciones, es salvar tambien otros registros, y en ese caso ya no sirven las MOV, quedando justificado el uso de SWAPF F,D por lo que siendo este el método general queda justificado que sea el recomendado.

Mas información en   http://www.todopic.com.ar/foros/index.php?topic=15920.0

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Comprobando funcionamiento (ASM basico)
« Respuesta #6 en: 12 de Febrero de 2007, 21:36:44 »
Amén.

 :D :D :D
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: Comprobando funcionamiento (ASM basico)
« Respuesta #7 en: 12 de Febrero de 2007, 22:59:06 »
      1º salvar W (lógico puesto que W se usará como puente para salvar los siguientes).
      2º salvar STATUS
      3º salvar resto de registros....

fartet, dejame agregar un par de comentarios que espero sirvan para ampliar tu excelente explicación.  :)

1) En pics con más de una página de memoria RAM el salvado del WREG no es tan simple como parece, hay que tener en cuenta donde lo guardaremos ya que si el pic tiene muchas páginas y no tiene memoria 'unbanked' entonces no es un tema trivial.  Habrá que estar seguro que esa posición de memoria no está ocupada en otras páginas con datos útiles!  Ej. en un pic16f873a
En el resto ya no importa donde están porque la ubicación puede ser perfectamente conocida al cambiar de página el STATUS a donde querramos (previo almacenamiento de su contenido en WREG).


3) En cualquier pic con más de una página de memoria de programa, es prácticamente fundamental guardar el PCLATH . (excepto que las interrupciones se activen en una región de programa perfectamente conocida, pero ya sería entrar en casos muy particulares).

Si usan el acceso indirecto en el vector de interrupción, y en el código entonces hay que guardar el FSR.  El acceso indirecto es una modalidad que no es tan usada pero cuando uno le agarra el gustito, es ideal para el manejo de buffers y se hace 'un vicio'  8)


Como regla general, conviene hacer una rutina que contemple el almacenamiento de ambos, después de todo son un solo algunas instrucciones las que se emplean y no viene mal tenerlos en cuenta así codificamos libremente.

- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado fartet

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 145
Re: Comprobando funcionamiento (ASM basico)
« Respuesta #8 en: 15 de Febrero de 2007, 17:43:07 »
Otro detalle muy elemental encontrado en bibliografia que creo que causa confusión.

En varios textos, cuando esplican el funcionamiento del Stack al saltar a subrutinas (o provocarse una interrupción) dicen que se guarda en el Stack la dirección de la instrucción en ejecución, y al finalizar la subrutina y ejecutar alguna de las instrucciones de retorno (return, retlw o retfie), dicen que el stack devuelve dicho valor incrementado con +1.

El error está en que esa descripción, si bien cuadra con el resultado final obtenido, entra en contradicción con el funcionamiento pipeline de los PIC, con dicho funcionamiento, junto a la microorden interna que carga el registro de instruciones asociado a la memoria de programa actua la microorden de incremento del contador de programa, por ello el contador de programa contiene la dirección inmediatamente siguiente a la de la instrucción activa (ya lleva el +1), y esa es la que se guarda en el stack, por lo que al efectuarse el retorno es tambien la que se devuelve al contador de programa sin necersidad de ser incrementada.