GBA | ASM | Clase Número 3: Instrucciones Básicas

Avisos

Like Tree24Gracias
  • 15 Post By Cheve
  • 2 Post By FEL!X
  • 2 Post By FEL!X
  • 1 Post By Cheve
  • 2 Post By Monika
  • 2 Post By Monika
Respuesta
 
Herramientas Desplegado
  #1  
16/06/2016
Predeterminado GBA | ASM | Clase Número 3: Instrucciones Básicas
Clase Número 3

Se recomienda leer las clases anteriores, disponibles en el final del post.

¡Que tal gente!
Retomemos dónde nos habíamos quedado anteriormente, que fue en los Registros del Procesador.

Recordemos:
  • 16 registros de 32 Bytes cada uno (Hasta 0xFFFFFFFF).
  • R0 a R7 Lo-Registers (Registros Bajos)
  • R8 a R12 Hi-Registers (Registros Altos)
  • R13 Stack Pointer (SP)
  • R14 Link Register (LR)
  • R15 Program Counter (PC)

Los conceptos de cada uno de ellos están en la clase anterior y entenderlos es bastante importante, aunque seguramente deberán (deberemos) ir a la clase anterior para releer varias cosas allí explicadas.

También tengamos en cuenta ésta notación:

Rd = Registro Destino.

Rm/Rn = Registro Normal

#0xZZZZZZ = Numero fijo

Empecemos con ésta clase:

Instrucciones Principales: Push y Pop

¿Recuerdan el Concepto de Pila? - Pues más les vale que lo hagan xD

Push:

Uso: Push - o empujar - almacena en una pila los valores de los registros dentro de los corchetes {}, y los deposita en el Stack - o pila - de nuestro procesador. Se usa en el 90% de los casos al hacer una rutina, y es lo primero que se escribe de la misma.

Sintaxis: Push { Lista de Registros, LR}

Ejemplo: Push {R0, R1, R2, R3, LR} ; Push {R0-R3,LR}

*Nota: Ambos ejemplos son equivalentes e igualmente válidos.

¿Para qué?: Para que al terminar nuestra rutina, con otra instrucción, podamos volver todo a "como estaba antes"

Pop:

Uso: Pop - o sacar - saca de la pila los valores almacenados de los registros dentro de los corchetes {}, y los carga en memoria. Se usa en el 90% de los casos al hacer una rutina, y es lo último que se escribe de la misma. (Siempre que haya un Push deberá haber un Pop).

Sintaxis: Pop { Lista de Registros, PC}

¿Para qué?: Para que al terminar nuestra rutina volvamos todo a "como estaba antes". (Cargamos lo que almacenó el Push, así puede seguir adelante la Rom desde donde estaba)


Aclaración Gráfica








Instrucciones de Cálculo

Add

Uso: Sumar valores entre registros o sumar un registro con un valor.

Sintaxis:
  • Add Rd, #0xZZ Donde 0xZZ tiene que estar entre 0x0 y 0xFF (Suma directa de un valor). Resultado: Rd = Rd + 0xZZ
  • Add Rd, Rn (Suma entre dos registros, con asignacion del valor al primero). Resultado: Rd = Rd + Rn.
  • Add Rd, Rn, #0xZZ Donde 0xZZ tiene que estar entre 0x0 y 0xFF (Suma entre un registro y un valor). Resultado: Rd = Rn + 0xZZ.
  • Add Rd, Rn, Rm (Suma entre dos registros). Resultado: Rd = Rn + Rm.


Sub

Uso: Restar valores a los registros o restar valores entre registros.

Sintaxis:
  • Sub Rd, #0xZZ Donde 0xZZ tiene que estar entre 0x0 y 0xFF (Resta directa de un valor). Resultado: Rd = Rd - 0xZZ
  • Sub Rd, Rn (Resta entre dos registros, con asignacion del valor al primero). Resultado: Rd = Rd - Rn.
  • Sub Rd, Rn, #0xZZ Donde 0xZZ tiene que estar entre 0x0 y 0xFF (Resta entre un registro y un valor). Resultado: Rd = Rn - 0xZZ.
  • Sub Rd, Rn, Rm (Resta entre dos registros). Resultado: Rd = Rn - Rm.



Mul

Uso: Multiplica Registros.

Sintaxis: Mul Rd, Rn . Resultado: Rd = Rd * Rn



Instrucciones de Carga de Datos

Ldr (Load Register)

Uso: Carga un valor de 4 Bytes directamente en el registro (Desde 0x00000000 hasta 0xFFFFFFFF).

Sintaxis:
  • Ldr Rd, [Rn] Resultado: Rd = Rn
  • Ldr Rd, =(0xFFFFFFFF) Resultado: Rd = 0xFFFFFFFF
  • Ldr Rd, [Rn, #0xFF] Resultado: Rd = Rn + 0xFF

Ldrh (Load Register Half-Word)
Uso: Carga un valor de 2 Bytes directamente en el registro (Desde 0x0000 hasta 0xFFFF).

Sintaxis:
  • Ldrh Rd, [Rn] Resultado: Rd = Rn
  • Ldrh Rd, =(0xFFFF) Resultado: Rd = 0xFFFF
  • Ldrh Rd, [Rn, #0xFF] Resultado: Rd = Rn + 0xFF

Ldrb (Load Register Byte)
Uso: Carga un valor de 1 Byte directamente en el registro (Desde 0x00 hasta 0xFF).

Sintaxis:
  • Ldrb Rd, [Rn] Resultado: Rd = Rn
  • Ldrb Rd, =(0xFF) Resultado: Rd = 0xFF
  • Ldrb Rd, [Rn, #0xFF] Resultado: Rd = Rn + 0xFF

_________________________________________

Str (Store Register)

Uso: Carga en una dirección 4 Bytes de data. La dirección es dada por el registro entre corchetes mientras que el otro es el que contiene la data.

Sintaxis:
  • Str Rd, [Rn] Rn = Rd (Si Rn = 0x02303000, en ese offset se escribirá lo que contiene Rd)
  • Str Rd, [Rn, #0xFF] [Rn + 0xFF] = Rd (Si Rn = 0x02303000, en ese offset + 0xFF (0x023030FF) se escribirá lo que contiene Rd)

Strh (Store Register Half-Word)

Uso: Carga en una dirección 2 Bytes de data. La dirección es dada por el registro entre corchetes mientras que el otro es el que contiene la data.

Sintaxis:
  • Strh Rd, [Rn] Rn = Rd (Si Rn = 0x02303000, en ese offset se escribirá lo que contiene Rd)
  • Strh Rd, [Rn, #0xFF] [Rn + 0xFF] = Rd (Si Rn = 0x02303000, en ese offset + 0xFF (0x023030FF) se escribirá lo que contiene Rd)

Strb (Store Register Half-Word)

Uso: Carga en una dirección 1 Bytes de data. La dirección es dada por el registro entre corchetes mientras que el otro es el que contiene la data.

Sintaxis:
  • Str Rd, [Rn] Rn = Rd (Si Rn = 0x02303000, en ese offset se escribirá lo que contiene Rd)
  • Str Rd, [Rn, #0xFF] [Rn + 0xFF] = Rd (Si Rn = 0x02303000, en ese offset + 0xFF (0x023030FF) se escribirá lo que contiene Rd)

Parte Práctica:


Inauguramos ésta sección en las clases/tutoriales realizando... ¡Nuestra primer rutina!

Vamos a usar el compilador de HackMew (Adjunto al final del tema) por lo que usaremos ésta plantilla por ahora:

Código:
.text
.align 2
.thumb
.thumb_func
.global Rutina_1

main:


@Aquí irá nuestra rutina


.align 2

@Aquí declararemos nuestras variables, en caso que necesitemos hacerlo
.text
.align 2
.thumb
.thumb_func

Son instrucciones que le dicen al compilador que estamos trabajando en thumb y alinea los bytes para ésto.

.global Rutina_1

Es opcional, sólo para darle un nombre a nuestra rutina

main:

Es una etiqueta, puede ser main: ; pepino: ; aca_empieza_mi_rutina_xdxd:
siempre terminada por " : " .

Para empezar a escribir nuestra rutina, primero necesitamos una idea, ¿A que si? xD

Pues recientemente quise hacer un script en el cual no me dejen entrar a una cueva hasta que mi pokémon tenga cierto nivel, pero no existe algo como un "GetPokemonLevel", así que lo haremos nosotros.

Entonces tenemos el primer paso:

1.Tener la Idea

El segundo paso sería obtener la mayor información posible del tema que nos atañe (Más adelante habrá una clase dedicada al 100% a ésto), para así saber o tener idea de como hacerlo y también si es posible de alguna manera.
Éste es un ejemplo simple, ya que sabemos que el nivel del pokémon ya está ahí, es solo extraerlo, meterlo en una variable y jugar con él.
¿Pero dónde está? Aquí entra nuestra amiga: Bulbapedia !

De aquí sacamos los datos para nuestra base, siendo así:


FR: 0x02024284

EM: 0x020244EC

RY: 0x03004360

Y luego tenemos una muy bonita tabla a la derecha:



Ésta tabla, nos explica fácilmente que, a partir de la dirección dada para nuestra base, tenemos distintos "Offsets" para cada dato particular de nuestro pokémon. (Nota: Los "Offsets" en la tabla están en decimal)

A nosotros nos interesa el offset del nivel,por lo que haremos lo siguiente:

FR: 0x02024284 + 0x54 (84 en Hex)

EM: 0x020244EC + 0x54 (84 en Hex)

RY: 0x03004360 + 0x54 (84 en Hex)


Quedándonos con los offset:

0x20242D8 --> Level primer pokémon en la party

0x2024540 --> Level primer pokémon en la party

0x03004360 --> Level primer pokémon en la party

Anotemos también por ahí:

Data total que hace a un pokémon: 100 Bytes

Direccion de la variable 0x800D en la Ram: 0x020270B6 + (0x800D * 2) (Gracias HackMew)

Direccion de la variable 0x800D en la Ram: 0x020275D6 + (0x800D * 2) (Gracias HackMew)


Direccion de la variable 0x800D en la Ram: 0x0201E8C2 + (0x800D * 2) (Gracias HackMew)


Bueno, y ya tenemos todo lo que necesitamos, copiemos la plantilla:
(Yo la escribiré para FR, pero será cuestión de cambiar el valor de las variables)

Paso 1


Código:
.text
.align 2
.thumb
.thumb_func
.global Rutina_1

main:
	push{r0-rx, LR} @Aún no sabemos cuántos registros usaremos
	
	pop {r0-rx, PC} 

.align 2




Paso 2

Código:
.text
.align 2
.thumb
.thumb_func
.global Rutina_1

main:
	push{r0-rx, LR}

	
	pop {r0-rx, PC} 

.align 2

.VAR:                            @De ésta forma declaramos que cada
	.word 0x020270B6 + (0x800D * 2)     @ vez que escribamos "VAR" nos referimos
                                                   @a dicha dirección

.PokemonLevel:
	.byte 0x20242D8


Paso 3

Código:
.text
.align 2
.thumb
.thumb_func
.global Rutina_1

main:
	push{r0-rx, LR}
	ldr r0, .PokemonLevel     
@car
go en r0 el valor de la variable "PokemonLevel" r0 = 0x020242D8
	ldr r1, .VAR              
@car
go en r1 el valor de la variable "VAR" r1 = 0x020370D0
	ldrb r0, [r0]	    
@car
go en r0 el valor byte que contiene el offset que contiene r0 (El lvl del primer pokémon)
	strb r0, [r1]               
@car
go en el offset que contiene r1 el valor byte que contiene r0   
	pop {r0-rx, PC} 

.align 2

.VAR:                            
	.word 0x020270B6 + (0x800D * 2)
.PokemonLevel:
	.byte 0x020242D8


Paso 4

Código:
.text
.align 2
.thumb
.thumb_func
.global Rutina_1

main:
	push {r0-r1, lr} @Arreglamos el push y el pop
	ldr r0, .PokemonLevel
	ldr r1, .VAR
	ldrb r0, [r0]
	strb r0, [r1]
	pop {r0-r1, pc} 

.align 2

.VAR:                            
	.word 0x020270B6 + (0x800D * 2)
.PokemonLevel:
	.byte 0x020242D8


Y listo, ya tenemos nuestra rutina lista para compilar y probar

Script Ejemplo



Código:
#dynamic 0x800000

'---------------
#org @start
callasm 0x8900001
buffernumber 0x0 LASTRESULT
msgbox  
@String
1 MSG_FACE '"Nivel del 1er pokémon: [buffer1]"
end


'---------
' Strings
'---------
#org  
@String
1
= Nivel del 1er pokémon: [buffer1]


Tarea: - Hacer que ésta rutina sirva para cualquier pokémon X de la party

Pista: Se puede usar la var 0x800D para ingresar un valor.

_____________________________

Clases Anteriores:

Clase 0 - Comprendiendo lo muy muy básico

Clase 1 - Comprendiendo lo Básico

Clase 2 - Registros, conociendo al procesador.

Clase Número 3: Instrucciones Básicas

Retirado del RomHacking






Skype: scriptercheve
Twitter: The Moon Lover


"Transforma tu mundo"





.



Última edición por Cheve; 16/06/2016 a las 04:11
  #2  
16/06/2016
Predeterminado Respuesta: GBA | ASM | Clase Número 3: Instrucciones Básicas
¡Yeaah! ¡La Instrucciones básicas! ¡Que grande eres!

Me he releído los temas anteriores y me he mirado a fondo las lecciones tomándome mi tiempo. Es una pasada, aunque admito que me ha costado entenderlo de primeras, le he dado muchas vueltas (risas).A continuación te voy a dejar unas “pocas” dudas o anotaciones por si me podrás ayudar ya que seguramente las dudas que tenga yo también las va a tener otro.
  • 1) El concepto más difícil de entender para mí ha sido comprender por qué usar la pila con el método Push-Pop o no . Te explico cómo lo entiendo yo, a ver si me equivoco o no:

Por lo que entiendo, lo que hacemos con push es hacer copia de los datos del los registros que vamos a usar. De esta forma manipulamos los registros a la vez que tenemos una copia de ellos en la pila. Cuando hemos terminado de usar los registros los restablecemos con el pop. De éste modo, usar Push y Pop nos sirve para utilizar los registros en un momento dado pero dejándolos al final de igual manera que al principio.

Por cierto, el gif va muy rápido y se hace difícil de comprenderlo, es mejor usar imágenes por pasos, como en la lección anterior.
  • 2) Las instrucciones de cálculo a simple vista creo que son fáciles de entender. Los Add/Sub Rd, Rn, Rm son sumas/restas entre dos registros cuyo valor está definido previamente ¿no?

Te pongo un ejemplo de cómo lo he entendido. Imaginémonos que quiero que pase algo dependiendo de que la suma entre valor de ataque y defensa del primer pokemon del equipo sea valor:

Offsets:
Código:
FR: 0x02024284 (pokemon data estrucutre offset) sabiendo que 0x84 es 132 en decimal:

Offset del valor de ataque: =  0x02024200 +0x84 + 0x5A (90 en Hex)=
= 0x02024200 + 0xDE (132+90= 222 en decimal) = 0x020242DE


Offset del valor de defensa = 0x02024200 +0x84 + 0x5C (92 en Hex) =
= 0x02024200 + 0xE0 (132+92= 224 en decimal) = 0x020242E0
Rutina:
Código:
.text
.align 2
.thumb
.thumb_func
.global Rutina_1

main:
	push {r0-r3, lr} 
ldr r0, .PkAttack
ldr r1, .PkDefense
ldr r2, .VAR
ldrb r0, [r0]
ldrb r1, [r1]
add r3, r0, r1
strb r3, [r2]
	pop {r0-r3, pc} 

.align 2

.VAR:                            
	.word 0x020270B6 + (0x800D * 2)
.PkAttack:
	.byte 0x020242DE

.PkDefense:
	.byte 0x020242E0

Planteado de esta forma ¿Mi rutina sería correcta?
Pd:¡Mi primera rutina wii! (risas)

Otras dudas relacionadas con el tema de las instrucciones son: (1) en caso de restar dos registros y el resultado sea inferior a cero (número negativo), ¿Qué ocurre con el valor? Y por otra parte (2) en caso de multiplicar dos números y el resultado decimal sea mayor a 255 es decir 0xFF para arriba (sea 0x 100, 0x101, 0x102…)
  • 3) En cuanto a las instrucciones de carga de datos creo que las he entendido (aunque me ha costado bastante xD). Aunque me gustaría confirmar si estoy en lo cierto: ¿Al cargar con un load los bytes se cargan en línea empezando por la izquierda? ¿También se leen por la izquierda?
Es decir:
Código:
ldr r0, 0xAABBCCDD 	
Registro 0 = DD CC BB AA	
 
ldr r0, 0xEE
Registro 0 = EE DD CC BB AA

ldr r1,r0
Registro 0 = EE DD CC BB AA
Registro 1 = EE 



Bueno, pos eso es todo, creo que no me dejo nada por preguntar (de momento x’D). Perdóname eh. Ya sabes que mis preguntas las hago con mucho amor.

* * *

Ha sido un tuto genial Cheve. Me lo he pasado genial leyendo e intentando entender sobre la materia. Investigando y al fin al cabo con el fin de comprenderlo todo a mi manera. Espero haber sido claro y que me puedas ayudar a entenderlo para saber si estoy en el buen camino (o si soy un fracaso D': y doy asco en ASM ).

Muchísimas gracias por el aporte, espero que haiga más en un futuro y así poder continuar de tanto en tanto en esta parte del romhacking en la que también me gustaría poder defenderme.


¡Un abrazo Cheve/ @MoonLover [/MENTION] !

Pd: Cuando tenga la tarea la postearé por aquí a ver qué tal.
Pd2: Perdón por ser tan largo como siempre, me enrollo más que una persiana. Pero ya sabes, lo hago con mucho hamorrrg
Gracias: Cheve y Guilly Alpha

Click para ver la firma




FEL!X



Premios




Galería (Link directo)



Aportaciones y participaciones



Algunas respuestas a posts y más posts





Respuesta: Cuantos años teneis? Que año Conocisteis Wah?

Respuesta: Con qué Pokémon te has encariñado y porqué?

Respuesta: GBA | Gráficos | [AVANZADO] ¡Añadir más frames a tus minis!

[Vídeo] Cuando Pokemon GO se vuelve violento
Respuesta: Rap de los Hackrom - Sage [A capella]
Respuesta: GBA | ASM | Clase Número 3: Instrucciones Básicas
Respuesta: ¿Cómo olvido a una chica? No puedo.
Respuesta: [Encuesta]¿Que encuentras mas divertido/entretenido al Rom Hackear/Makear?
* * *
Respuesta: [Cosas De WaH Ep2]¡¡5 Cosas Paranormal Que Nos Han Sucedido!!
Respuesta: FR| ASM| Salto en cualquier dirección.
Respuesta: [Cosas De WaH Ep1]¡¡10 Cosas Sobre Nosotros!!
¡fel!xidades! (Gracias a todos)

¡Ya están aquí!: Resultados PWaH 2015

Respuesta: ¿Qué estás escuchando ahora? (2)
* * *

Respuesta: [Relato de invierno] Chicago.
Respuesta: ¡TIPOS DE HACKERS! ¡Dime qué clase eres tú!
[TAG del MangaAnime]
Respuesta: [FR][DUDA]Comandos de dinero
[Por Una Wah Unida]
Respuesta: Mis motivos de estar aqui
* * *

Respuesta: Psicólogo para el psicólogo, filósofo para el filósofo~
Respuesta: ¿Qué estás escuchando ahora?
Respuesta: [Historia] Hijos del bosque, hijos del viento
Respuesta: [IDEA] Jugador se pueda liar
Respuesta: ¿Cuál es vuestro arquetipo de personaje favorito?
Respuesta: [Encuesta] ¿Cuál fue tu primer juego de pokemon?
* * *


Respuesta: [Test] ¿Qué tipo de personalidad eres?(Viva el comandante FEL!X)

Tu TOP 5 de animes (Mi propio top)
Respuesta:Pregunta a todos los spriters (Mi punto de vista)
Respuesta: IDEA | Nuevos Tipos Elementales 8El tipo experto)
Respuesta: IDEA | Nuevos Tipos de Evolucion (El caso de Machamp )

¡Un abrazo!

  #3  
19/06/2016
Predeterminado Respuesta: GBA | ASM | Clase Número 3: Instrucciones Básicas
Dicho por MoonLover Ver mensaje

Código:
.text
.align 2
.thumb
.thumb_func
.global Rutina_1

main:
	push {r0-r1, lr} 
	ldr r0, .PokemonLevel
	ldr r1, .VAR
	ldrb r0, [r0]
	strb r0, [r1]
	pop {r0-r1, pc} 

.align 2

.VAR:                            
	.word 0x020270B6 + (0x800D * 2)
.PokemonLevel:
	.byte 0x020242D8
Dicho por MoonLover Ver mensaje

Tarea: - Hacer que ésta rutina sirva para cualquier pokémon X de la party

Pista: Se puede usar la var 0x800D para ingresar un valor.
Mmm, no estoy seguro. Pero si tuviera que hacerlo supongo que haría primero un script donde guardara en 0x800D (Lastresult) el slot/ubicación del pokemon que estoy eligiendo.

Como sabemos que los pokemons se eligen en 6 slots empezando por el primero =0x0 y terminando en 0x5, el valor de 0x800D será en este rango de valores.

Sabemos que el data de un pokemon ocupa 100 bytes en decimal, es decir 0x64 por lo que si el data del level del primer pokemon es 0x020242D8, el del segundo (0x1) será 0x020242D8 + 0x64.

Sabiendo que el incremento es el mismo, concluimos que:
Offset de data de level del pokemon y= 0x020242D8 + 0x64*y


Por lo tanto, todo lo que tenemos a continuación son simples mates. Solo tenemos que decidir “y” (=slot del pokemon) y sacar el byte que es el nivel que queremos guardar en la misma 0x800D al final de la rutina para poder usarlo en el juego.

La rutina que propongo entonces es:

Código:
.text
.align 2
.thumb
.thumb_func
.global Rutina_1

main:
	push {r0-r2, lr} 
	ldr r0, .PokemonLevel
	ldr r1, .VAR
	ldrb r2, .PokemonIncrementoLevel
	ldrb r1, [r1]
	mul r2, r1
	add r0, r2
	ldrb r0, [r0]	
	strb r0, [r1]
	pop {r0-r2, pc} 

.align 2

.VAR:                            
	.word 0x020270B6 + (0x800D * 2)
.PokemonLevel:
	.byte 0x020242D8 

.PokemonIncrementoLevel:
	.byte 0x64
Como vemos en rojo tenemos una parte diferente respecto a la rutina que solo funciona para el primer poke a modo de ejemplo dada por Cheve.

En éste caso usamos un registro mas, r2, por lo que usamos en total 3 registros; r0,r1yr2. El paso en rojo consiste en cargar el valor del LASRESULT guardado en el registro 1, multiplicarlo por el incremento y sumárselo al offset. Es decir, la ecuación que expliqué antes:
Offset de data de level del pokemon y= 0x020242D8 + 0x64*y

Y eso es todo, la continuación es la misma que en el la rutina únicamente válida para el primer poke. El byte de nivel se carga dependiendo de la dirección del slot dada y y se guarda en 0x800D para su posterior uso.

* * *
Y esto es todo, tarea presentada lista para revisar maestro Cheve. ¡Gracias por la lección jefe!

Un abrazo.


Pd: Cheve, ahora tienes pendiente los dos posts del tema x’D. Quería esperar para añadir la tarea pero…no C:

Pd2: Espero que te guste mi tarea. Ya sabes, lo hago con cariño x’D
Gracias: Cheve y DeadApolo

Click para ver la firma




FEL!X



Premios




Galería (Link directo)



Aportaciones y participaciones



Algunas respuestas a posts y más posts





Respuesta: Cuantos años teneis? Que año Conocisteis Wah?

Respuesta: Con qué Pokémon te has encariñado y porqué?

Respuesta: GBA | Gráficos | [AVANZADO] ¡Añadir más frames a tus minis!

[Vídeo] Cuando Pokemon GO se vuelve violento
Respuesta: Rap de los Hackrom - Sage [A capella]
Respuesta: GBA | ASM | Clase Número 3: Instrucciones Básicas
Respuesta: ¿Cómo olvido a una chica? No puedo.
Respuesta: [Encuesta]¿Que encuentras mas divertido/entretenido al Rom Hackear/Makear?
* * *
Respuesta: [Cosas De WaH Ep2]¡¡5 Cosas Paranormal Que Nos Han Sucedido!!
Respuesta: FR| ASM| Salto en cualquier dirección.
Respuesta: [Cosas De WaH Ep1]¡¡10 Cosas Sobre Nosotros!!
¡fel!xidades! (Gracias a todos)

¡Ya están aquí!: Resultados PWaH 2015

Respuesta: ¿Qué estás escuchando ahora? (2)
* * *

Respuesta: [Relato de invierno] Chicago.
Respuesta: ¡TIPOS DE HACKERS! ¡Dime qué clase eres tú!
[TAG del MangaAnime]
Respuesta: [FR][DUDA]Comandos de dinero
[Por Una Wah Unida]
Respuesta: Mis motivos de estar aqui
* * *

Respuesta: Psicólogo para el psicólogo, filósofo para el filósofo~
Respuesta: ¿Qué estás escuchando ahora?
Respuesta: [Historia] Hijos del bosque, hijos del viento
Respuesta: [IDEA] Jugador se pueda liar
Respuesta: ¿Cuál es vuestro arquetipo de personaje favorito?
Respuesta: [Encuesta] ¿Cuál fue tu primer juego de pokemon?
* * *


Respuesta: [Test] ¿Qué tipo de personalidad eres?(Viva el comandante FEL!X)

Tu TOP 5 de animes (Mi propio top)
Respuesta:Pregunta a todos los spriters (Mi punto de vista)
Respuesta: IDEA | Nuevos Tipos Elementales 8El tipo experto)
Respuesta: IDEA | Nuevos Tipos de Evolucion (El caso de Machamp )

¡Un abrazo!

  #4  
27/06/2016
Predeterminado Respuesta: GBA | ASM | Clase Número 3: Instrucciones Básicas
@FEL!X , no he compilado las rutinas, pero no te haz equivocado en nada y deberían funcionar ambas.
Nada que corregirte, lo de la pila lo haz entendido perfe C:


Sólo una cosa, aunque aún no haya explicado como hacerlo, debes tener en cuenta que la Var 0x800D en realidad no está limitada a un valor entre 0x0 y 0x5, por lo que ahí podría generar un error, pero luego habrá otra clase donde se controlará eso.

Gracias por ir siguiendo las clases!

PD: Recién cuando ví tu mensaje estoy terminando de montar el Windows7 xD
Gracias: FEL!X

Retirado del RomHacking






Skype: scriptercheve
Twitter: The Moon Lover


"Transforma tu mundo"





.


  #5  
27/06/2016
Predeterminado Respuesta: GBA | ASM | Clase Número 3: Instrucciones Básicas
Dicho por MoonLover Ver mensaje
FEL!X, no he compilado las rutinas, pero no te haz equivocado en nada y deberían funcionar ambas.
Nada que corregirte, lo de la pila lo haz entendido perfe C:
¡Yeeeah! Te loveo. Me alegra oírlo. Me mola pensar que estoy siguiendo el hilo de las lecciones.

Dicho por MoonLover Ver mensaje
Sólo una cosa, aunque aún no haya explicado como hacerlo, debes tener en cuenta que la Var 0x800D en realidad no está limitada a un valor entre 0x0 y 0x5, por lo que ahí podría generar un error, pero luego habrá otra clase donde se controlará eso.
He tenido en cuenta el Lastresult porque lo tenía a mano, tienes toda la razón. Para este caso también podría haber usado en su lugar cualquier variable segura. El tema de esto es ver si la var 0x800D se toca con ello sí, tendre en cuenta el peligro Gracias por remarcarlo

* * *

Relacionado con el tema tengo estas dos dudas, en caso de restar dos registros y el resultado sea inferior a cero (número negativo), ¿Qué ocurre con el valor?

Y por otra parte, ¿En caso de multiplicar dos números y el resultado decimal sea mayor a 255 es decir 0xFF para arriba (sea 0x 100, 0x101, 0x102…), como se almacena el número? (Supongo que lo que hace es apelotonar el segundo byte de momento)

* * *

Ya sabes tío, me encanta que aportes estos temas al foro. Nos servirá a muchos. ¡Un abrazo!

Click para ver la firma




FEL!X



Premios




Galería (Link directo)



Aportaciones y participaciones



Algunas respuestas a posts y más posts





Respuesta: Cuantos años teneis? Que año Conocisteis Wah?

Respuesta: Con qué Pokémon te has encariñado y porqué?

Respuesta: GBA | Gráficos | [AVANZADO] ¡Añadir más frames a tus minis!

[Vídeo] Cuando Pokemon GO se vuelve violento
Respuesta: Rap de los Hackrom - Sage [A capella]
Respuesta: GBA | ASM | Clase Número 3: Instrucciones Básicas
Respuesta: ¿Cómo olvido a una chica? No puedo.
Respuesta: [Encuesta]¿Que encuentras mas divertido/entretenido al Rom Hackear/Makear?
* * *
Respuesta: [Cosas De WaH Ep2]¡¡5 Cosas Paranormal Que Nos Han Sucedido!!
Respuesta: FR| ASM| Salto en cualquier dirección.
Respuesta: [Cosas De WaH Ep1]¡¡10 Cosas Sobre Nosotros!!
¡fel!xidades! (Gracias a todos)

¡Ya están aquí!: Resultados PWaH 2015

Respuesta: ¿Qué estás escuchando ahora? (2)
* * *

Respuesta: [Relato de invierno] Chicago.
Respuesta: ¡TIPOS DE HACKERS! ¡Dime qué clase eres tú!
[TAG del MangaAnime]
Respuesta: [FR][DUDA]Comandos de dinero
[Por Una Wah Unida]
Respuesta: Mis motivos de estar aqui
* * *

Respuesta: Psicólogo para el psicólogo, filósofo para el filósofo~
Respuesta: ¿Qué estás escuchando ahora?
Respuesta: [Historia] Hijos del bosque, hijos del viento
Respuesta: [IDEA] Jugador se pueda liar
Respuesta: ¿Cuál es vuestro arquetipo de personaje favorito?
Respuesta: [Encuesta] ¿Cuál fue tu primer juego de pokemon?
* * *


Respuesta: [Test] ¿Qué tipo de personalidad eres?(Viva el comandante FEL!X)

Tu TOP 5 de animes (Mi propio top)
Respuesta:Pregunta a todos los spriters (Mi punto de vista)
Respuesta: IDEA | Nuevos Tipos Elementales 8El tipo experto)
Respuesta: IDEA | Nuevos Tipos de Evolucion (El caso de Machamp )

¡Un abrazo!

  #6  
22/10/2017
Predeterminado Respuesta: GBA | ASM | Clase Número 3: Instrucciones Básicas
Había visto hace tiempo este tema, pero nunca me había parado a probar las rutinas hasta hoy, incitado por este tema, y estuve mirando y no me funcionaban ninguna de las dos, ni la de cheve ni la de felix, por eso decidí mirar el motivo y el de la de cheve es el siguiente:

Código:
.byte 0x020242D8
.word 0x020242D8
No entendí muy bien porque desde un principio pusiste .byte cuando se trata de una word.
Compilar me compilaba igual, pero a la hora de probar el script no funcionaba.

Rutina con eso puesto

Código:
.text
.align 2
.thumb
.thumb_func
.global Rutina_1

main:
	push {r0-r1, lr} @Arreglamos el push y el pop
	ldr r0, .PokemonLevel
	ldr r1, .VAR
	ldrb r0, [r0]
	strb r0, [r1]
	pop {r0-r1, pc} 

.align 2

.VAR:                            
	.word 0x020270B6 + (0x800D * 2)
.PokemonLevel:
	.word 0x020242D8


Luego la de felix directamente no compilaba y era por eso también, cambiando el .byte por el .word ya lo hacía, el problema es que a la hora de probarlo tampoco funcionaba. Por tanto decidí hacer yo una adaptación de la rutina y este es el resultado:

Código:
.text
.align 2
.thumb
.thumb_func
.global Rutina_1

main:
	push {r0-r2, lr} 
	ldr r0, .PokemonParty
	ldr r1, .VAR
	ldrb r2, .IncrementoPokemon
        mul r2, r2, r1 
	add r0, r2, #0x54
	ldrb r0, [r0]	
	strb r0, [r1]
	pop {r0-r2, pc} 

.align 2

.VAR:                            
	.word 0x020370D0
.PokemonParty:
	.word 0x02024284
.IncrementoPokemon:
	.byte 0x64
Después de revisar y revisar no entiendo que es lo que está mal, lo que hago es multiplicar el valor que haya en la variable 0x800D por 0x64 para saber de que slot del equipo se trata y luego al resultado de eso le sumo #0x54 para que marque el nivel del Pokémon. Haciendo calculos y comprobándolos serían perfectos. Haciendo la multiplicación sacamos uno de estos datos:
0x02024284 100b Party Pokemon 1
0x020242E8 100b Party Pokemon 2
0x0202434C 100b Party Pokemon 3
0x020243B0 100b Party Pokemon 4
0x02024414 100b Party Pokemon 5
0x02024478 100b Party Pokemon 6
Y por la suma de 0x54 a uno de los offsets anteriores se saca el offset del nivel de ese slot del equipo.
El error que me sale a la hora de compilar es: inmediate value out of range

El script que pretendo utilizar para sacar el valor de 0x800D es este:

Script

Código:
#dynamic 0x800000

#org @start
lockall
special 0x9F
waitstate
copyvar 0x8004 0x800D
compare 0x800D 0x7
if 0x1 goto @cancel
callasm 0x880201
buffernumber 0x0 0x800D
msgbox @a 0x6
releaseall
end

#org @a
= El nivel de este Pokémon es: [buffer1]

#org @cancel
releaseall
end


Ya me estoy volviendo loco, ayuda por favor xDD @Cheve J. @Enamorat de Aaró @Kaiser de Emperana siento molestar

EDIT: Después de fijarme un poco me di cuenta de que el error de compilar podría venir del comando add, y así era, luego de modificar la rutina de esta manera:
Código:
        ...
        mul r2, r2, r1
        add r2, r2, #0x54
	add r0, r0, r2
	ldrb r0, [r0]
        ...
Ya compila, pero sigue sin funcionar
La diferencia entre la genialidad y la estupidez es que la genialidad tiene un límite.
~Albert Einstein


Última edición por Inferno; 22/10/2017 a las 22:51
  #7  
22/10/2017
Predeterminado Re: Respuesta: GBA | ASM | Clase Número 3: Instrucciones Básicas
Dicho por Inferno Ver mensaje
Había visto hace tiempo este tema, pero nunca me había parado a probar las rutinas hasta hoy, incitado por este tema, y estuve mirando y no me funcionaban ninguna de las dos, ni la de cheve ni la de felix, por eso decidí mirar el motivo y el de la de cheve es el siguiente:

Código:
.byte 0x020242D8
.word 0x020242D8
No entendí muy bien porque desde un principio pusiste .byte cuando se trata de una word.
Compilar me compilaba igual, pero a la hora de probar el script no funcionaba.

Rutina con eso puesto

Código:
.text
.align 2
.thumb
.thumb_func
.global Rutina_1

main:
	push {r0-r1, lr} @Arreglamos el push y el pop
	ldr r0, .PokemonLevel
	ldr r1, .VAR
	ldrb r0, [r0]
	strb r0, [r1]
	pop {r0-r1, pc} 

.align 2

.VAR:                            
	.word 0x020270B6 + (0x800D * 2)
.PokemonLevel:
	.word 0x020242D8


Luego la de felix directamente no compilaba y era por eso también, cambiando el .byte por el .word ya lo hacía, el problema es que a la hora de probarlo tampoco funcionaba. Por tanto decidí hacer yo una adaptación de la rutina y este es el resultado:

Código:
.text
.align 2
.thumb
.thumb_func
.global Rutina_1

main:
	push {r0-r1, lr} @Arreglamos el push y el pop
	ldr r0, .PokemonLevel
	ldr r1, .VAR
	ldrb r0, [r0]
	strb r0, [r1]
	pop {r0-r1, pc} 

.align 2

.VAR:                            
	.word 0x020270B6 + (0x800D * 2)
.PokemonLevel:
	.word 0x020242D8
Después de revisar y revisar no entiendo que es lo que está mal, lo que hago es multiplicar el valor que haya en la variable 0x800D por 0x64 para saber de que slot del equipo se trata y luego al resultado de eso le sumo #0x54 para que marque el nivel del Pokémon. Haciendo calculos y comprobándolos serían perfectos. Haciendo la multiplicación sacamos uno de estos datos:


Y por la suma de 0x54 a uno de los offsets anteriores se saca el offset del nivel de ese slot del equipo.
El error que me sale a la hora de compilar es: inmediate value out of range

El script que pretendo utilizar para sacar el valor de 0x800D es este:

Script

Código:
#dynamic 0x800000

#org @start
lockall
special 0x9F
waitstate
copyvar 0x8004 0x800D
compare 0x800D 0x7
if 0x1 goto @cancel
callasm 0x880201
buffernumber 0x0 0x800D
msgbox @a 0x6
releaseall
end

#org @a
= El nivel de este Pokémon es: [buffer1]

#org @cancel
releaseall
end


Ya me estoy volviendo loco, ayuda por favor xDD @Cheve J. @Enamorat de Aaró @Kaiser de Emperana siento molestar

EDIT: Después de fijarme un poco me di cuenta de que el error de compilar podría venir del comando add, y así era, luego de modificar la rutina de esta manera:
Código:
        ...
        mul r2, r2, r1
        add r2, r2, #0x54
	add r0, r0, r2
	ldrb r0, [r0]
        ...
Ya compila, pero sigue sin funcionar
Bueno, con el edit que pusiste ya se fue uno de los problemas. El otro está en:
Código:
...
ldr r1, .VAR
...
Lo que estás cargando en r1 es el puntero al valor de la variable, no el valor de la variable, así que lo que estás multiplicando termina siendo: 0x020370D0 * 0x64 = 0xc9581140. Que se sale por un poquiiiito de la ram xD
Solo te falta leer el valor almacenado en la dirección:
Código:
...
ldr r1, .VAR
ldrh r1, [r1]
...
Creo que eso sería todo.
Saludos.

EDIT: NO, no bastaba con eso, me saltee el final de la rutina.
Yo la dejaría algo tal que así: (ESTO ESTÁ MAL, VER MI SIGUIENTE MENSAJE)
Código:
.text
.align 2
.thumb
.thumb_func
.global Rutina_1

main: 
	ldr r0, .PokemonParty
	ldr r1, .VAR
	ldrh r3, [r1]
	mov r2, #0x64
	mul r2, r2, r3 
	add r2, r2, #0x54
	add r0, r0, r2
	ldrb r0, [r0]	
	strb r0, [r1]
	bx lr

.align 2

.VAR:                            
	.word 0x020370D0
.PokemonParty:
	.word 0x02024284
Los push de los registros r0 a r3 son innecesarios. Y el push de lr también ya que no llamás a ninguna otra función (si hubieras hecho un bl si lo sería).
Gracias: Lunos y Inferno

o_O

Última edición por Monika; 23/10/2017 a las 22:09
  #8  
23/10/2017
Corazón Respuesta: Re: Respuesta: GBA | ASM | Clase Número 3: Instrucciones Básicas
Dicho por Kaiser de Emperana Ver mensaje
Yo la dejaría algo tal que así:
Código:
.text
.align 2
.thumb
.thumb_func
.global Rutina_1

main: 
	ldr r0, .PokemonParty
	ldr r1, .VAR
	ldrh r3, [r1]
	ldrb r2, .IncrementoPokemon
        mul r2, r2, r3 
	add r2, r2, #0x54
	add r0, r0, r2
	ldrb r0, [r0]	
	strb r0, [r1]
	bx lr

.align 2

.VAR:                            
	.word 0x020370D0
.PokemonParty:
	.word 0x02024284
.IncrementoPokemon:
	.byte 0x64
Esto es lo que necesitaba. Yo justamente le pregunté a @FEL!X si podia echarle un vistazo pues el compilador tiraba 2 o 3 errores, pero veo que ya no será necesario. Asi que, esta rutina guarda el nivel de un Pokémon seleccionado por el jugador (por ejemplo, mediante el Special 0x9F) en la variable 0x800D, ¿correcto?
  #9  
23/10/2017
Predeterminado Respuesta: GBA | ASM | Clase Número 3: Instrucciones Básicas
Todavía me sigue fallando, no se si ya soy yo o el script o la rutina... xD

(Ponedlo a x2, aunque no hay mucho que ver)



El script que uso es el de ahí arriba.

Si alguien la prueba y me dice si le pasa lo mismo ayudaría.
La diferencia entre la genialidad y la estupidez es que la genialidad tiene un límite.
~Albert Einstein

  #10  
23/10/2017
Predeterminado Re: Respuesta: GBA | ASM | Clase Número 3: Instrucciones Básicas
Dicho por Lunos Ver mensaje
Esto es lo que necesitaba. Yo justamente le pregunté a @FEL!X si podia echarle un vistazo pues el compilador tiraba 2 o 3 errores, pero veo que ya no será necesario. Asi que, esta rutina guarda el nivel de un Pokémon seleccionado por el jugador (por ejemplo, mediante el Special 0x9F) en la variable 0x800D, ¿correcto?
Exáctamente, eso hace. Pero con cambiar el 0x54 por otro valor de acá y bueno, la cantidad de bytes que lee, se podrían leer bastantes más datos.

Dicho por Inferno Ver mensaje
Todavía me sigue fallando, no se si ya soy yo o el script o la rutina... xD

(Ponedlo a x2, aunque no hay mucho que ver)



El script que uso es el de ahí arriba.

Si alguien la prueba y me dice si le pasa lo mismo ayudaría.
Ya edite mi mensaje, había un error en la rutina que se me había pasado.
------------------------
Otro edit más...
Y por esto es que hay probar bien las cosas y no sólo con el caso más sencillo
El puntero a la variable 0x8004 estaba mal en la rutina y el script necesitaba unos retoques.
Rutina:
Código:
 
.text
.align 2
.thumb
.thumb_func
.global Rutina_1

main: 
	ldr r0, .PokemonParty
	ldr r1, .VAR
	ldrh r3, [r1]
	mov r2, #0x64
	mul r2, r2, r3 
	add r2, r2, #0x54
	add r0, r0, r2
	ldrb r0, [r0]	
	strb r0, [r1]
	bx lr

.align 2

.VAR:                            
	.word 0x020370C0
.PokemonParty:
	.word 0x02024284
Script:
Código:
#dynamic 0x800000

#org @start
lockall
special 0x9F
waitstate
compare 0x8004 0x7
if 0x1 goto @cancel
callasm 0x880201
buffernumber 0x0 0x8004
msgbox @a 0x6
releaseall
end

#org @a
= El nivel de este Pokémon es: [buffer1]

#org @cancel
releaseall
end
Ya la probé bien, esta vez no debería de haber errores...
Gracias: FEL!X y Inferno

o_O

Última edición por Monika; 23/10/2017 a las 22:08
Respuesta

Herramientas
Desplegado

Permisos para publicar mensajes
No puedes crear nuevos temas
No puedes responder mensajes
No puedes subir archivos adjuntos
No puedes editar tus mensajes

Los BB code están Activado
Los Emoticones están Activado
El código [IMG] está Activado
El Código HTML está Desactivado
Trackbacks are Activado
Pingbacks are Activado
Refbacks are Desactivado



Extra
Estilo clásico
La franja horaria es GMT +1. Ahora son las 11:28.