ASM: Ejecuar un JP a una dirección de memoria almacenada en otra (puntero)

Page 1/3
| 2 | 3

By Visualedu

Resident (33)

Visualedu's picture

13-07-2019, 01:36

Hola, en ensamblador tengo un puntero (una dirección donde almaceno otra) y quiero recuperar esa dirección y hacer un JP a la misma.

Lo estoy haciendo como podéis ver abajo. Funciona pero me gustaría saber si se puedo optimizar porque es una rutina que llamo de continuo.

ld hl,(punteroPantalla)
ld a,(hl)
ld e,a
inc hl
ld a,(hl)
ld d,a

ld h,d
ld l,e

jp (hl)

Por otro lado, ¿se podría hacer un call a la dirección destino? (en vez de un JP)

Gracias, Edu

Login or register to post comments

By Manel46

Champion (431)

Manel46's picture

13-07-2019, 10:19

ld hl,(punteroPantalla)
ld e,(hl)
inc hl
ld d,(hl)
ex de,hl ;intercambia hl por de
jp (hl)

Así es mas simple.
No existe call (hl), debes hacer rutina equivalente.

By Visualedu

Resident (33)

Visualedu's picture

13-07-2019, 10:47

Gracias!!. Lo voy a cambiar ahora mismo Big smile
Edu

By Manel46

Champion (431)

Manel46's picture

13-07-2019, 13:10

Tema jp (hl):
Puedes llamar a una subrutina como:
call etiqueta
Luego donde sea escribes:
etiqueta: jp(hl)
Lo que haya en hl, debe terminar con: ret

By Manel46

Champion (431)

Manel46's picture

13-07-2019, 15:02

Su usas sjasm, las etiquetas no tienen por que terminar con ":". Eso si, es indispensable que comiencen en la primera columna. Las instrucciones, por lo menos, en la segunda.

By Visualedu

Resident (33)

Visualedu's picture

14-07-2019, 01:16

Hola, pues no es mala idea. Yo lo había hecho al revés. La llamada a jp(hl) estaba dentro de una rutina. Y esa rutina acababa obligatoriamente con el jp(hl) porque el código al que apunta hl tiene un ret. Es una solución más elegante y no me obliga a terminar la rutina que llama al jp(hl).Gracias de nuevo! Big smile

By [WYZ]

Champion (406)

[WYZ]'s picture

16-07-2019, 19:53

Estaría bien poder hacer: LD PC,(PunteroPantalla)... a ver si se te ocurre algo Smile

Program Counter#
The z80 needs to keep track of where it's executing code. It stores that address in the 16 bit register pc. You can't directly modify this register with regular instructions.

The only way to modify pc is to push a new value onto the Stack and use a ret. The ret will use the last value on the stack as the new Program Counter. It'll jump to that address and start executing code again.

By Mortimer

Rookie (17)

Mortimer's picture

16-07-2019, 22:11

También lo puedes hacer con código automodificante, delante de la variable en RAM con el puntero a dónde quieras saltar pones otra variable de un byte con C3h (El código de JP), luego desde el código saltas ahí y ejecturás el JP a tu puntero, con la ventaja de no tener que modificar ningún registro.

By [WYZ]

Champion (406)

[WYZ]'s picture

16-07-2019, 22:52

Qué bueno! para funcionar en RAM es genial Mortimer.

En ROM no se me ocurre nada mejor que:

LD	HL,[puntero]
PUSH 	HL
RET

By Mortimer

Rookie (17)

Mortimer's picture

17-07-2019, 22:24

Esa técnica se usaba mucho en los antiguos juegos de PC, cuando aún se programaban en ensamblador. En lugar de tener varias variables que consultar para que el programa las consulte y tome una dirección u otra, las variables eran directamente dónde había que saltar, sólo había que darle los valores mágicos adecuados para que saltara a los sitios correctos en lugar de los típicos valores arbitrarios 0,1,2...

Si se usan en el interior de bulces anidados la mejora en ciclos pueden ser muy importantes.

By [WYZ]

Champion (406)

[WYZ]'s picture

18-07-2019, 13:14

Es una técnica espectacular y superoptimizada. Hacer un JP Adress_puntero-1, donde ya tienes escrito el $C3.
Gracias!

Page 1/3
| 2 | 3