Registrarse

[RH - ASM] Problema con comparaciones (cmp)

Estado
Cerrado para nuevas respuestas.

Rasputin

Usuario de platino
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.
 
Última edición:

MetalKaktus

A la luz del quinto día, mira al este
Miembro insignia
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 ;)
 
Última edición:

Rasputin

Usuario de platino
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
 

MetalKaktus

A la luz del quinto día, mira al este
Miembro insignia
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

Usuario de platino
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
 

MetalKaktus

A la luz del quinto día, mira al este
Miembro insignia
Has cambiado el bgt por bls en los dos sitios que tienes puestos?
 

MetalKaktus

A la luz del quinto día, mira al este
Miembro insignia
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

Usuario de platino
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.
 
Última edición:

Rasputin

Usuario de platino
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:



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! :)
 
Estado
Cerrado para nuevas respuestas.
Arriba