Whack a Hack Foro!

Whack a Hack Foro! (/foro/)
-   ROM Hacking (https://whackahack.com/foro/f-211/rom-hacking/)
-   -   [RH - ASM] Problema con comparaciones (cmp) (https://whackahack.com/foro/t-58304/problema-comparaciones-cmp)

Rasputin 14/12/2018 17:34

Problema con comparaciones (cmp)
 
Buenas tardes! Estoy desarrollando una que recorre una serie de listas para llegar a un valor concreto y almacenarlo en la variable 8007 (lo explico de manera escueta porque prefiero ser lo mas objetivo posible, si alguien le interesa saber para que es que lo diga y lo ponga en los comentarios sin ningun problema :) )

El problema es el siguiente:

Necesito que me devuelva un valor =<4 en la variable 8007, y para ello realizo una resta de -4 sobre el valor actual de un registro en forma de bucle. El fallo esta en que al realizar el comando cmp para comparar dicho valor, no lo compara y evidentemente sigue adelante con la siguiente orden de la rutina.

El valor que contiene R2 en el momento de realizar la comparacion es correcto (lo he comprobado, y en los casos de prueba era 31), pero no consigo que entre el bucle por la comparación.

Dejo aqui dicha rutina por si alguien me puede echar una mano:

Código:

.align 2
.thumb

Cargar_Banco:
        push {lr}
        ldr r0, .banco_actual @;Carga en r0 el offset del banco actual
        ldrb r0, [r0] @;Almacena en r0 el primer byte (numero del banco actual)
        mov r1, #0x4 @;Inserta el valor 0x4 en r1
        mul r1, r0                @;Multiplica el valor de r0 por r1 y lo inserta en r1 para obtener el numero de entrada del banco
        ldr r2, .cabezal_banco @;Carga Tabla de cabezales en r2
        add r1, r2, r1 @;Añade desplazamiento sobre el offset cabezal_banco y lo sobrescribe en r1
       
Cargar_Mapa:       
        ldr r1, [r1] @; Carga el pointer correspondiente del Cabezal_Banco
        ldr r0, .mapa_actual @;Carga en r0 el offset del mapa actual
        ldrb r0, [r0] @;Almacena en r0 el primer byte (numero del mapa actual)
        mov r2, #0x4 @;Inserta el valor 0x4 en r2
        mul r2, r0 @;Multiplica el valor de r0 por r2 y lo inserta en r2 para obtener el numero de entrada del mapa
        add r2, r1, r2 @;Añade desplazamiento sobre el offset banco y lo sobrescribe en r2
        ldr r2, [r2] ;@Carga puntero del cabezal del mapa
        ldr r2, [r2] @; Carga puntero de offset del mapa
       
       
Cargar_Info:       
        mov r1, #0xC @;Inserta el valor 0xC (12) en r1
        add r1, r2, r1 @;Añade desplazamiento sobre el offset actual y lo sobrescribe en r1
        ldr r1, [r1] @; Carga puntero del Data del mapa r1
        @; INSERTAR AQUI LAS VARIABLES PARA POSICION DE GETPLAYERPOS()
        mov r2, #0x1 @; Desplazamiento para cargar segundo byte de la halfword
        add r2, r1, r2
        ldr r2, [r2] @; Carga contenido del puntero en r2
        @; HASTA AQUI FUNCIONA!
        mov r1, #0x0 @; Contador
        @; EL PROBLEMA ESTA AQUI!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! NO COMPARA LAS VARIABLES?
        cmp r2, #0x4
        bgt Bucle @;Si no va al bucle
        b Estado @;Si es menor o igual a 3 sale del bucle
       
Bucle:
        add r1, r1, #0x1 @; Sumar 1 al valor actual del contador
        sub r2, r2, #0x4 @; Restar 1 al valor actual del valor de la variable a comparar
        cmp r2, #0x4
        bgt Bucle
        b Estado
       
Estado:
        ldr r3, .var_8007
        strb r1, [r3] @;////// PONER R2 SI NO FUNCIONA
        pop {pc}       
       
.align 2
.var_8007: .word 0x20375E6
.var_8008: .word 0x20375E8
.var_8009: .word 0x20375EA
.cabezal_banco: .word 0x0886BBE4
.banco_actual: .word 0x03015E59
.mapa_actual: .word 0x03015E58
.facing_heroe: .word 0x0202065A

De antemano muchas gracias a cualquiera que este leyendo esto por su atención, y mas a quien intente ayudarme de alguna forma jejeje

Un saludo!

PD: hay algunos nombres de variables (entiendase por var_8008, .facing_heroe, etc) que no se han utilizado todavia debido a que la rutina esta en fase de desarrollo. Tambien puede que haya algún comentario mal explicado o errado.

Annatar 14/12/2018 18:00

Re: Problema con comparaciones (cmp)
 
Quieres comprobar si el valord e r2 es menor o igual a 4? Pues chico no se como quieres hacerlo.

Código:

cmp r2, #0x4
bgt bucle
b estado


Mmmm, no veo como quieres hacer eso. Mira, prueba con esto, porque real,ente no se si el comando bgt existe.

Código:

cmp r2, #0x4
bls estado
b bucle

Es como un ciclo while, se comprueba la posibilidad de salir del bucle, y de lo contrario vuelve a repetir el ciclo.

esto hace que si r2 es menor o igual a 4 vayas a estado, de lo contrario (else) se repite el bucle. Y eso, ya me dirás si te funciona.

----------------------------

Te recomiendo mirar este tuto: https://whackahack.com/foro/t-56345/tutotial-asm-fbi ;)

Rasputin 14/12/2018 18:09

Re: Problema con comparaciones (cmp)
 
Buenas! Gracias por la ayuda.

El comando lo saque de un tutorial de este mismo foro si no me confundo, pero si no te suena seguramente este mal jaja.

Acabo de probar y el juego se queda pillado. Me imagino que se quede pillado en el bucle.

Habia probado con esto:

Código:


mov r1, #0x0 @; Contador
        strb r2, [r3]
        @; EL PROBLEMA ESTA AQUI!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! NO COMPARA LAS VARIABLES?
        cmp r3, #0x4
        ble Estado @;Si no va al bucle
        b Bucle @;Si es menor o igual a 3 sale del bucle
       
Bucle:
        add r1, r1, #0x1 @; Sumar 1 al valor actual del contador
        sub r3, r3, #0x4 @; Restar 1 al valor actual del valor de la variable a comparar
        cmp r3, #0x4
        ble Estado
        b Bucle
       
Estado:
        ldr r2, .var_8007
        strb r1, [r2] @;////// PONER R2 SI NO FUNCIONA
        pop {pc}

Pero ademas de tardar un rato considerable en devolver el valor, el valor que devuelve el contador es mucho mayor de lo que debe jeje

Annatar 14/12/2018 18:10

Re: Problema con comparaciones (cmp)
 
Cita:

Dicho por Rasputin (Mensaje 433382)
Buenas! Gracias por la ayuda.

El comando lo saque de un tutorial de este mismo foro si no me confundo, pero si no te suena seguramente este mal jaja.

Acabo de probar y el juego se queda pillado. Me imagino que se quede pillado en el bucle.

Habia probado con esto:

Código:


mov r1, #0x0 @; Contador
        strb r2, [r3]
        @; EL PROBLEMA ESTA AQUI!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! NO COMPARA LAS VARIABLES?
        cmp r3, #0x4
        ble Estado @;Si no va al bucle
        b Bucle @;Si es menor o igual a 3 sale del bucle
       
Bucle:
        add r1, r1, #0x1 @; Sumar 1 al valor actual del contador
        sub r3, r3, #0x4 @; Restar 1 al valor actual del valor de la variable a comparar
        cmp r3, #0x4
        ble Estado
        b Bucle
       
Estado:
        ldr r2, .var_8007
        strb r1, [r2] @;////// PONER R2 SI NO FUNCIONA
        pop {pc}

Pero ademas de tardar un rato considerable en devolver el valor, el valor que devuelve el contador es mucho mayor de lo que debe jeje

Te has equivocado al escribirlo amigo :P

es bls y no ble

Rasputin 14/12/2018 18:14

Re: Problema con comparaciones (cmp)
 
Disculpame :no-way: copie la que no era jaja
Con bls el resultado es 8F, el valor de r2 en el momento de restar es 31, por lo que el valor del contador no coincide '^^

Ademas de tardar un rato en reaccionar tambien jeje puede ser por las operaciones de restar en bucle? porque en los casos de prueba cuando cargaba el valor de r2 en la var 8007 para comprobar que era el valor correcto lo hacia rapidisimo

Annatar 14/12/2018 18:18

Re: Problema con comparaciones (cmp)
 
Has cambiado el bgt por bls en los dos sitios que tienes puestos?

Rasputin 14/12/2018 18:19

Re: Problema con comparaciones (cmp)
 
Cita:

Dicho por Turambar (Mensaje 433388)
Has cambiado el bgt por bls en los dos sitios que tienes puestos?

Si si jej me he asegurado

Annatar 14/12/2018 18:24

Re: Problema con comparaciones (cmp)
 
Lo primero, el contador no te va a funcionar, por el echo de que estás seteado el valor 0 siempre que haces el ciclo. Siempre que vayas a usar un contador en ASM debes mover un cero al registro antes de entrar al bucle y una vez dentro solo debes sumarle uno por cada vez que se repita el ciclo.

Y ese registro no puedes usarlo para dentro del bucle, pues está reservado a ser un contador, y si lo sobreescribes ya no servirá de nada.

Igualmente un contador se usa para simular ciclos for, que hacen que se repita un bucle n veces. Pero si lo que quieres es hacer un while, no necesitas de contador, que es lo que tu quieres hacer.

Si me explicas con detalle lo que quieres hacer te echaré una mano.

Rasputin 14/12/2018 19:18

Re: Problema con comparaciones (cmp)
 
No he entendido eso primero jj
Código:

mov r1, #0x0 @; Contador
        strb r2, [r3]
        @; EL PROBLEMA ESTA AQUI!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! NO COMPARA LAS VARIABLES?
        cmp r3, #0x4
        bls Estado @;Si no va al bucle
        b Bucle @;Si es menor o igual a 3 sale del bucle

Asta donde yo entiendo (porfavor corrigeme si me equivoco), mov r1, #0x0 setea r0 a 0, antes de entrar al bucle y luego llama a este. Una vez dentro con
Código:

add r1, r1, #0x1 @; Sumar 1 al valor actual del contador
suma un 1 sobre el valor anterior de r1 y lo sobrescribe en r1 de nuevo.

El contador no es para que el bucle (en este caso while efectivamente) se rompa, sino para saber un valor concreto teniendo en cuenta las vueltas que da el bucle. Me explico:

Esta rutina es para saber el "tipo de movimiento" (0,1,2,3.. segun AMap) que tiene el player delante de el para ejecutar un objeto que hace que el jugador salte. La intencion es que no pueda saltar a un bloque con el valor 1 (no pasar) segun AMap.

Para ello recorre una serie de listas segun valores de la ram como el cabezal del mapa, banco y mapa, para llegar finalmente a la informacion de dicho mapa.

La informacion que hay alli se almacenan por halfwords, el primero indica el numero del bloque y el segundo (no lo tengo muy claro pero me vale para lo que quiero hacer) es el movimiento permitido.

R2 en este caso carga el segundo valor de dicha halfword que es el valor actual del movimiento permitido, peeeeero no son los mismos valores para cada mapa (en unos el valor 1 de AMap es 0x5, en otros 0x2), por lo que es necesario saber en que punto se encuentra.

Para ello voy restando 4 al valor de r2 y comparandolo con <=4 y sumando 1 al contador. Una vez llegado a esto, rompe el bucle y el valor del contador sera el valor actual del bloque, ya que cuando sea 4 o menor sera el valor 0 del AMap.

Finalmente devuelve este valor en 8007 con el valor segun AMap que me permite interpretar si el script de salto se puede ejecutar o no, como muchas otras cosas que se me ocurren jejeje

Se que es un poco royo pero queria hacer alguna rutina que fuera dinamica para cada mapa, sin tener que hacer una lista con las areas de cada mapa (area de figuras irregulares) ya que es muy engorroso a mi parecer.

De momento carga solo el primer bloque del mapa en el que te encuentres, pero con getplayerpos puedo saber en que bloque se encuentra el hero y recorrer la lista de halfwords para concretarlo.

Acabo de probar esto y funciona a la perfeccion y rapidisimo!

Código:

.align 2
.thumb

Main:
        push {lr}
        mov r0, #0x31
        mov r1, #0x0 @; Contador
        cmp r0, #0x4
        bls Estado @;Si no va al bucle
        b Bucle @;Si es menor o igual a 3 sale del bucle
       
Bucle:
        add r1, r1, #0x1 @; Sumar 1 al valor actual del contador
        sub r0, r0, #0x4 @; Restar 1 al valor actual del valor de la variable a comparar
        cmp r0, #0x4
        bls Estado
        b Bucle
       
Estado:
        ldr r2, .var_8007
        strb r1, [r2] @;////// PONER R2 SI NO FUNCIONA
        pop {pc}       
       
.align 2
.var_8007: .word 0x20375E6

Por lo que me da a entender que hay algun problema con el valor de R2, pero tampoco entiendo porque si cuando lo guardaba en 8007 daba el valor correcto.

Rasputin 14/12/2018 20:36

Re: Problema con comparaciones (cmp)
 
Código:

mov r2, #0x1 @; Desplazamiento para cargar segundo byte de la halfword
add r2, r1, r2
ldrb r2, [r2] @; Carga contenido del puntero en r2 <--- SOLUCION

De momento esta es la solucion temportal que he encontrado. Aqui la prueba del funcionamiento:

https://imgur.com/a/Qeyh60S

Por si no cargara el GIF:

https://imgur.com/a/Qeyh60S

Como he dicho, de momento solo analiza el primer bloque del mapa donde te encuentres (y solo valores superiores o iguales a 4, por lo que si fuera 0 seguramente no lo analizara correctamente), y he puesto un valor de 1 y D segun los movimientos permitidos del AMap para comprobar que funciona.

La idea es ejecutar el comando getplayerpos, y llamar a la rutina para que analice el facing y las coordenadas para que analice los bloques concretos.

Muchas gracias por la ayuda, el tutorial me sirvio de mucho.

Si a alguien se le ocurre alguna forma de depurar la rutina para hacerla mas pequeña o cualquier idea de uso para otras cosas, no dudeis en hacermelo saber!

Cuando este terminada la posteare por si a alguien mas le puede valer.

Un saludo! :)


La franja horaria es GMT +1. Ahora son las 21:29.

Powered por vBulletin™ Version 3.8.9
Copyright © 2019 vBulletin Solutions, Inc. All rights reserved.
SEO by vBSEO 3.6.1
Traducido por vBsoporte - vBulletin en español
Credits System provided by vBCredits II Deluxe (Lite) - vBulletin Mods & Addons Copyright © 2019 DragonByte Technologies Ltd.
User Alert System provided by Advanced User Tagging (Lite) - vBulletin Mods & Addons Copyright © 2019 DragonByte Technologies Ltd.

vBulletin Optimisation provided by vB Optimise (Pro) - vBulletin Mods & Addons Copyright © 2019 DragonByte Technologies Ltd.