Ayuda para entender fragmento en asm de z80

Foro dedicado a la programación en todo tipo de sistemas clásicos.
Avatar de Usuario
Dustin
Commodore 128
Commodore 128
Mensajes: 101
Registrado: 19 May 2014, 09:28
Sistema Favorito: Amstrad CPC
primer_sistema: Amstrad CPC
consola_favorita: Atari 2600
Primera consola: Atari 2600
Gracias dadas: 1 vez
Gracias recibidas: 7 veces

Ayuda para entender fragmento en asm de z80

Mensajepor Dustin » 30 Sep 2015, 14:54

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

Avatar de Usuario
zup
Amiga 2500
Amiga 2500
Mensajes: 2971
Registrado: 04 Sep 2009, 20:07
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Nintendo DS/3DS
Primera consola: Nintendo GameBoy
Ubicación: Navarra
Gracias dadas: 68 veces
Gracias recibidas: 326 veces
Contactar:

Re: Ayuda para entender fragmento en asm de z80

Mensajepor zup » 30 Sep 2015, 15:05

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.
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start.
Además vendo cosas!

Urusergi
MSX Turbo R
MSX Turbo R
Mensajes: 405
Registrado: 21 Dic 2011, 10:11
Ubicación: Madrid
Gracias dadas: 656 veces
Gracias recibidas: 23 veces

Re: Ayuda para entender fragmento en asm de z80

Mensajepor Urusergi » 30 Sep 2015, 16:20

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

Avatar de Usuario
radastan
Amiga 2500
Amiga 2500
Mensajes: 4542
Registrado: 11 Jun 2007, 19:29
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Sega Genesis/Megadrive
Primera consola: TV Games/Pong Clone
Ubicación: Córdoba
Gracias dadas: 9 veces
Gracias recibidas: 40 veces
Contactar:

Re: Ayuda para entender fragmento en asm de z80

Mensajepor radastan » 30 Sep 2015, 16:35

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.
Yo tengo una máquina del tiempo, se llama ZX Spectrum, siempre me devuelve a los buenos momentos.
(\.../) (\.../) (\.../) (\.../)
( *.*) ('.'= ) ('.'= ) ('.'= )
(")_(") (")_(") (")_(") (")_(")
╔═══╦═══╦═══╦══╦══╗
║╔═╗║╔═╗║╔═╗╠╣╠╩╣╠╝
║║─║║╚══╣║─╚╝║║─║║
║╚═╝╠══╗║║─╔╗║║─║║
║╔═╗║╚═╝║╚═╝╠╣╠╦╣╠╗
╚╝─╚╩═══╩═══╩══╩══╝

Avatar de Usuario
Haplo
MSX Turbo R
MSX Turbo R
Mensajes: 278
Registrado: 14 Abr 2014, 22:24
Sistema Favorito: PC
primer_sistema: Spectrum +2
consola_favorita: Sony PlayStation 1
Primera consola: Nintendo NES/Clónica
Ubicación: Ciudad Real
Gracias dadas: 33 veces
Gracias recibidas: 5 veces

Re: Ayuda para entender fragmento en asm de z80

Mensajepor Haplo » 30 Sep 2015, 17:11

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:

Avatar de Usuario
Dustin
Commodore 128
Commodore 128
Mensajes: 101
Registrado: 19 May 2014, 09:28
Sistema Favorito: Amstrad CPC
primer_sistema: Amstrad CPC
consola_favorita: Atari 2600
Primera consola: Atari 2600
Gracias dadas: 1 vez
Gracias recibidas: 7 veces

Re: Ayuda para entender fragmento en asm de z80

Mensajepor Dustin » 30 Sep 2015, 17:50

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

Urusergi
MSX Turbo R
MSX Turbo R
Mensajes: 405
Registrado: 21 Dic 2011, 10:11
Ubicación: Madrid
Gracias dadas: 656 veces
Gracias recibidas: 23 veces

Re: Ayuda para entender fragmento en asm de z80

Mensajepor Urusergi » 30 Sep 2015, 22:19

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.

Avatar de Usuario
radastan
Amiga 2500
Amiga 2500
Mensajes: 4542
Registrado: 11 Jun 2007, 19:29
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Sega Genesis/Megadrive
Primera consola: TV Games/Pong Clone
Ubicación: Córdoba
Gracias dadas: 9 veces
Gracias recibidas: 40 veces
Contactar:

Re: Ayuda para entender fragmento en asm de z80

Mensajepor radastan » 30 Sep 2015, 22:54

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.
Yo tengo una máquina del tiempo, se llama ZX Spectrum, siempre me devuelve a los buenos momentos.
(\.../) (\.../) (\.../) (\.../)
( *.*) ('.'= ) ('.'= ) ('.'= )
(")_(") (")_(") (")_(") (")_(")
╔═══╦═══╦═══╦══╦══╗
║╔═╗║╔═╗║╔═╗╠╣╠╩╣╠╝
║║─║║╚══╣║─╚╝║║─║║
║╚═╝╠══╗║║─╔╗║║─║║
║╔═╗║╚═╝║╚═╝╠╣╠╦╣╠╗
╚╝─╚╩═══╩═══╩══╩══╝

Urusergi
MSX Turbo R
MSX Turbo R
Mensajes: 405
Registrado: 21 Dic 2011, 10:11
Ubicación: Madrid
Gracias dadas: 656 veces
Gracias recibidas: 23 veces

Re: Ayuda para entender fragmento en asm de z80

Mensajepor Urusergi » 30 Sep 2015, 23:08

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.

Avatar de Usuario
radastan
Amiga 2500
Amiga 2500
Mensajes: 4542
Registrado: 11 Jun 2007, 19:29
Sistema Favorito: Spectrum 16Kb/48Kb
primer_sistema: Spectrum 16Kb/48Kb
consola_favorita: Sega Genesis/Megadrive
Primera consola: TV Games/Pong Clone
Ubicación: Córdoba
Gracias dadas: 9 veces
Gracias recibidas: 40 veces
Contactar:

Re: Ayuda para entender fragmento en asm de z80

Mensajepor radastan » 01 Oct 2015, 12:59

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.
Yo tengo una máquina del tiempo, se llama ZX Spectrum, siempre me devuelve a los buenos momentos.
(\.../) (\.../) (\.../) (\.../)
( *.*) ('.'= ) ('.'= ) ('.'= )
(")_(") (")_(") (")_(") (")_(")
╔═══╦═══╦═══╦══╦══╗
║╔═╗║╔═╗║╔═╗╠╣╠╩╣╠╝
║║─║║╚══╣║─╚╝║║─║║
║╚═╝╠══╗║║─╔╗║║─║║
║╔═╗║╚═╝║╚═╝╠╣╠╦╣╠╗
╚╝─╚╩═══╩═══╩══╩══╝


Volver a “Programación”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 2 invitados