Página 1 de 2

Ayuda para entender fragmento en asm de z80

Publicado: 30 Sep 2015, 14:54
por Dustin
Hola,

Tengo el siguiente código del "Programming the z80":

Código: Seleccionar todo

            LD B, COUNTH
            LD DE,-1
LOOPA: LD HL,COUNTL
LOOPB: ADD HL,DE
            JR C,LOOPB
            DJNZ LOOPA


Mi idea iniclal era que por cada decremento de B, HL hace un bucle desde FFFF hasta 0, pero no veo como se mantiene el flag de acarreo a 1 hasta el final del bucle. He probado con un IDE/emulador de z80 el siguiente código:

Código: Seleccionar todo

       LD B,0
       LD DE, 0FFH   
LOOPA: LD HL,0
LOOPB: ADD HL, DE
      JR C,LOOPB
       DJNZ LOOPA


Y nunca se jumple la condición JR C

En el libro, en teoría, explica el asunto en un párrafo, per la verdad Zacks no tenía su mejor día cuando lo escribió...

Gracias
Saludos

Re: Ayuda para entender fragmento en asm de z80

Publicado: 30 Sep 2015, 15:05
por zup
Dos cosas que me llaman la atención:

- En el primer código, no se decrementa b veces 65536, sino b veces COUNTL (o eso creo).
- En el segundo código, DE=255. No restas uno, sino que sumas 255. Para restar uno, DE debería valer 0xFFFF

Vale, ya me lo he pensado mejor. En el primer código, si COUNTL es 30000, en cada paso por el bucle la suma da uno menos (30000+65535=29999+acarreo), hasta que HL=0. En ese momento, la suma ya no da acarreo y se sale del bucle. El primer programa cuenta COUNTH*COUNTL veces.

En tu caso (segundo código), el bucle inicializa HL a 0. La primera suma no da acarreo y te sales del bucle.

El código del libro puede contar como máximo 255*65535 iteraciones. Para contar b*65536 iteraciones necesitarás otro tipo de bucle.

Mi sugerencia de bucle (muy clásico):

Código: Seleccionar todo

   ld b,COUNTH
   ld de,COUNTL
LOOP:   dec de
   ld a,d
   or e
   jr nz, LOOP:
   djnz LOOP


Lo he hecho de memoria, pero debería ser capaz de contar b*65536+de iteraciones.

Re: Ayuda para entender fragmento en asm de z80

Publicado: 30 Sep 2015, 16:20
por Urusergi
Dustin escribió:Hola,

Tengo el siguiente código del "Programming the z80":

Código: Seleccionar todo

            LD B, COUNTH
            LD DE,-1
LOOPA: LD HL,COUNTL
LOOPB: ADD HL,DE
            JR C,LOOPB
            DJNZ LOOPA


Mi idea iniclal era que por cada decremento de B, HL hace un bucle desde FFFF hasta 0, pero no veo como se mantiene el flag de acarreo a 1 hasta el final del bucle.


Mola! es un "truco" muy chulo.
Consiste en sumar &FFFF (=-1) al número declarado en COUNTL. Al sumar números de 16 bits sin acarreo sólo se altera el flag de Carry, de modo que se activa a "1" cuando se produce desbordamiento del resultado de la suma, y de esa manera mantenemos el carry a uno casi todo el rato.
¿Cuál es el único caso en el que no hay desbordamiento? cuando HL alcanza el valor &0000, que al sumarle &FFFF obtenemos &FFFF \:D/

Para que te funcione como quieres tienes que poner COUNTL EQU &FFFF

Re: Ayuda para entender fragmento en asm de z80

Publicado: 30 Sep 2015, 16:35
por radastan
Dustin escribió:Hola,

Tengo el siguiente código del "Programming the z80":

Código: Seleccionar todo

            LD B, COUNTH
            LD DE,-1
LOOPA: LD HL,COUNTL
LOOPB: ADD HL,DE
            JR C,LOOPB
            DJNZ LOOPA


Venga, para que no se sientan incómodos los ajenos al ASM les voy a explicar el código de forma sencilla:

LD B, COUNTH -> LD = "le dá". B le dá a COUNTH. Seguramente estén peleados por algo y COUNTH lleva las de perder.
LD DE,-1 -> Lo mismo, pero DE se lo piensa y no le da a nadie.
LOOPA: LD HL,COUNTL -> LOOPA = efecto zoom + "le dá" HL a COUNTH. Ya tiene que ser la hostia buena que la cámara hace zoom del bofetón de HL a COUNTL.
LOOPB: ADD HL,DE -> Es otro efecto de zoom distinto, pero en esta ocasión HL se une a DE, lo que viene a continuación va a ser gordo.
JR C,LOOPB -> JR = "el del gorro de Dallas". ¿Ves? venía algo gordo, y viene con C, hasta hacen otro zoom.
DJNZ LOOPA -> DJNZ = "follón de la hostia", con zoom y todo, es la escena final.

Espero que así todos entiendan un poquito más de ensamblador, como véis es sencillote.

Está clarísimo que es un fragmento del guión de un episodio molón de Dallas.

Re: Ayuda para entender fragmento en asm de z80

Publicado: 30 Sep 2015, 17:11
por Haplo
Un matiz para entender el desenlace de la peli, DJNZ LOOPA quiere decir "DescoJoNZiar y zoom", lo cual es un formato clásico usado por ejemplo en los fatality de MK. :ugeek:

Re: Ayuda para entender fragmento en asm de z80

Publicado: 30 Sep 2015, 17:50
por Dustin
Haplo escribió:Un matiz para entender el desenlace de la peli, DJNZ LOOPA quiere decir "DescoJoNZiar y zoom", lo cual es un formato clásico usado por ejemplo en los fatality de MK. :ugeek:

No, si leer ensamblador es fácil, lo complicado es la pronunciación

-- Actualizado 30 Sep 2015, 19:41 --

Urusergi escribió:
Dustin escribió:Hola,

Tengo el siguiente código del "Programming the z80":

Código: Seleccionar todo

            LD B, COUNTH
            LD DE,-1
LOOPA: LD HL,COUNTL
LOOPB: ADD HL,DE
            JR C,LOOPB
            DJNZ LOOPA


Mi idea iniclal era que por cada decremento de B, HL hace un bucle desde FFFF hasta 0, pero no veo como se mantiene el flag de acarreo a 1 hasta el final del bucle.


Mola! es un "truco" muy chulo.
Consiste en sumar &FFFF (=-1) al número declarado en COUNTL. Al sumar números de 16 bits sin acarreo sólo se altera el flag de Carry, de modo que se activa a "1" cuando se produce desbordamiento del resultado de la suma, y de esa manera mantenemos el carry a uno casi todo el rato.
¿Cuál es el único caso en el que no hay desbordamiento? cuando HL alcanza el valor &0000, que al sumarle &FFFF obtenemos &FFFF \:D/

Para que te funcione como quieres tienes que poner COUNTL EQU &FFFF


Y efectivamente funciona :D.

Gracias

-- Actualizado 30 Sep 2015, 19:46 --

zup escribió:Dos cosas que me llaman la atención:

- En el primer código, no se decrementa b veces 65536, sino b veces COUNTL (o eso creo).
- En el segundo código, DE=255. No restas uno, sino que sumas 255. Para restar uno, DE debería valer 0xFFFF

Vale, ya me lo he pensado mejor. En el primer código, si COUNTL es 30000, en cada paso por el bucle la suma da uno menos (30000+65535=29999+acarreo), hasta que HL=0. En ese momento, la suma ya no da acarreo y se sale del bucle. El primer programa cuenta COUNTH*COUNTL veces.

En tu caso (segundo código), el bucle inicializa HL a 0. La primera suma no da acarreo y te sales del bucle.

El código del libro puede contar como máximo 255*65535 iteraciones. Para contar b*65536 iteraciones necesitarás otro tipo de bucle.

Mi sugerencia de bucle (muy clásico):

Código: Seleccionar todo

   ld b,COUNTH
   ld de,COUNTL
LOOP:   dec de
   ld a,d
   or e
   jr nz, LOOP:
   djnz LOOP


Lo he hecho de memoria, pero debería ser capaz de contar b*65536+de iteraciones.


La verdad es que, me parece a mi, este bucle se entiende mejor. Se nota un poco que el libro es antiguo, porque hace cualquier invento para ahorrarse instrucciones (cuando no algunos ciclos de procesador). Imagino (porque tener no tengo ni idea :D ) que a día de hoy ni con el microcontrolador más cutrecillo hace falta afinar tanto la velocidad de ejecución del código.

Saludos

Re: Ayuda para entender fragmento en asm de z80

Publicado: 30 Sep 2015, 22:19
por Urusergi
Dustin escribió:La verdad es que, me parece a mi, este bucle se entiende mejor. Se nota un poco que el libro es antiguo, porque hace cualquier invento para ahorrarse instrucciones (cuando no algunos ciclos de procesador). Imagino (porque tener no tengo ni idea :D ) que a día de hoy ni con el microcontrolador más cutrecillo hace falta afinar tanto la velocidad de ejecución del código.

Saludos


No es porque el libro sea antiguo, sino que con el z80 hace falta optimizar si o si ;)
En este caso no ahorra instrucciones, pero te permite prescindir del Acumulador, cosa que a veces viene muy bien.

Re: Ayuda para entender fragmento en asm de z80

Publicado: 30 Sep 2015, 22:54
por radastan
Urusergi escribió:
Dustin escribió:La verdad es que, me parece a mi, este bucle se entiende mejor. Se nota un poco que el libro es antiguo, porque hace cualquier invento para ahorrarse instrucciones (cuando no algunos ciclos de procesador). Imagino (porque tener no tengo ni idea :D ) que a día de hoy ni con el microcontrolador más cutrecillo hace falta afinar tanto la velocidad de ejecución del código.

Saludos


No es porque el libro sea antiguo, sino que con el z80 hace falta optimizar si o si ;)
En este caso no ahorra instrucciones, pero te permite prescindir del Acumulador, cosa que a veces viene muy bien.


Más imporante es ahorrar memoria o ganar velocidad, el acumulador es lo de menos.

Re: Ayuda para entender fragmento en asm de z80

Publicado: 30 Sep 2015, 23:08
por Urusergi
radastan escribió:Más importante es ahorrar memoria o ganar velocidad, el acumulador es lo de menos.


Ufffff, ni te imaginas la de veces que eché de menos el poder usar el acumulador :lol: y encima teniendo que optimizar en tamaño y velocidad de todas maneras.

Re: Ayuda para entender fragmento en asm de z80

Publicado: 01 Oct 2015, 12:59
por radastan
Urusergi escribió:
radastan escribió:Más importante es ahorrar memoria o ganar velocidad, el acumulador es lo de menos.


Ufffff, ni te imaginas la de veces que eché de menos el poder usar el acumulador :lol: y encima teniendo que optimizar en tamaño y velocidad de todas maneras.


Es cuestión de cómo plantees las rutinas y el programa. El acumulador es para lo que es, donde se hacen todas las operaciones, no tiene sentido reservarlo a menos que lo hagas aposta.