Registrarse

[RH - ASM] Clase 1

Estado
Cerrado para nuevas respuestas.

Katherine

Omnipresente
Miembro de honor
Clase 1

Al ser la primera clase no vamos a meternos de lleno en el mundo del ASM, ya que antes debemos entender ciertas cosas referente a este. Por lo tanto, la clase de hoy se centrará en los puntos siguientes.

• ROM y RAM (offsets...)
• Registros (registros bajos, sp, lr, pc…)
• Compilando una rutina

ROM

ROM es la abreviatura de Read Only Memory. Es el archivo que almacena todos los datos de nuestro juego (scripts, paletas de tiles, midis...). Si abrís una ROM mediante un editor hexadecimal veréis los datos ordenador por bytes en sus respectivos offsets.

Byte: Equivalente a 8 bits, es decir, es igual a ocho dígitos binarios. Si no sabéis que es el código binario buscadlo en Internet. Por lo que respecta al ASM en el Rom Hacking un byte es un conjunto de dos números en sistema hexadecimal. Es decir, un byte es aquel número hexadecimal entre 00 y FF, ambos incluidos.

Offset: Un offset es la dirección donde se almacena un byte. En el próximo ejemplo gráfico se entenderá mejor.


En el ASM la ROM será nuestro libro de referencia. De ahí sacaremos muchos de los datos que necesitemos (los nombres de los ataques, el tipo de los movimientos...).

RAM

RAM es la abreviatura de Random Acces Memory. Es donde se almacenan todos los datos a la hora de jugar al juego. Por ejemplo, almacena los datos de nuestros Pokemon, los textos que aparecen en pantalla, nuestro dinero...

De hecho, la mayoría, si no son todos, los comandos del XSE se basan en modificar los datos de la RAM.

La RAM se ordena de la misma forma que la ROM, los datos se almacenan en offsets en forma de bytes.

La propia RAM será nuestra otra fuente de información en el ASM, además, es el objetivo a editar al final de la rutina. Es decir, todas las rutinas tratan de editar la RAM.

Registros

A partir de aquí nos adentramos en lo que viene siendo el ASM. Un registro es lo equivalente a una variable, pero en vez de almacenar una half word (dos bytes) es capaz de almacenar una word (cuatro bytes).

En el ASM usaremos los registros para almacenar en ellos los datos que nosotros queramos para usarlos a nuestro antojo.

Por lo tanto, un registro es capaz de almacenar un valor entre 0x00000000 y 0xFFFFFFFF, ambos incluidos.

¿Qué registros existen?

A partir de ahora veréis mucho la nomenclatura de llamar r a un registro. Por ejemplo, al primer registro se le llamará r0, al siguiente r1 (nótese que se empieza desde 0 y no desde 1).

Los registros bajos (low registers) son los que normalmente usaremos para gestionar nuestros datos. Es tos registros son desde el r0 hasta el r7. Traquilos, son de sobra para nosotros.

Los registros altos (high registers) son los registro entre r8 y r12. Son registros que solo algunas instrucciones pueden acceder, aunque a veces sean de uso general (nosotros usaremos solo los anteriores).

SP (stack pointer) o r13 es un registro que guarda el punto más alto de la pila (stack). Para explicar lo que es una pila citaré a @Cheve_X

Una pila es una cantidad de elementos puestos unos sobre otros, es una estructura de datos.
Podemos considerar a una pila vacía así:


Parece una estantería donde luego apilaremos Libros. La estantería sería nuestra memoria y los libros nuestros punteros.
Ésta estructura tiene una forma muy peculiar de tratamiento de informacion, lo que la hace especial, y se conoce como: LIFO

Last
In
First
Out

Es decir, "El último en entrar, es el primero en salir".
Una vez más, ilustremos:

Supongamos que queremos hacer una pila de libros de distintos colores, meteremos primero el libro de color amarillo.
Como nuestra pila está vacía, irá al fondo de la misma:




Ahora bien, si agregamos otro elemento a la pila, digamos un libro Azul, éste tambien irá por encima de todo:


Ahora, como son elementos apilados, no podemos sacar el de más abajo sin antes extraer el de arriba. Es decir, para sacar el amarillo, antes debemos sacar el Azul:




LR (link register) o r14 es el registro que almacena el offset de la siguiente rutina (comando) del último bl (branch with link) que se haya ejecutado. Paso a paso, un bl es un tipo de comando que hace saltar a un offset de la RAM automáticamente (con retorno). Pues precisamente para eso sirve el lr, para recordar “donde habíamos dejado la anterior rutina” dicho de una forma poco profesional.

PC (program counter) o r15 es un registro que almacena el offset de la siguiente rutina a ejecutar (es decir, el offset actual +2). En caso de haber un bl el valor de pc se guardará en el lr antes mencionado.

Si no habéis entendido el sp, lr y pc no os agobiéis. No hace falta entender como funcionan a la perfección pues no afecta demasiado a las rutinas que vayamos a hacer.

Compilar una rutina

Para todo aquel que tenga un Sistema Operativo de Windows es muy sencillo. Lo explicaré paso a paso.

1) Escribir la rutina en un editor de texto como Notepad (el más recomendado al venir ya instalado de fábrica).

2) Guardar el archivo en formato .asm en la misma carpeta que el compilador. Os pondré una demostración gráfica para entenderlo bien.


3) Arrastrar el archivo .asm al archivo llamado “thumb”. Si la rutina está
bien hecha y no tiene ningún fallo de sintaxis se os debería aparecer un archivo con el mismo nombre pero .bin.

4) Insertarla (el archivo .bin) en un espacio vacío de la ROM que termiene en 0, 4, 8 o C. Para llamar a la rutina desde un script simplemente hay que usar el comando callasm 0x(offset de la rutina .asm

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

Esto es todo por hay, como ya había dicho esta semana no hay tarea, pero a la próxima si que abra. Recordad, a la mínima duda preguntad por aquí ;)

 

Laquin

Usuario mítico
Aquí van mis preguntas:
  • Sé que las variables se almacenan en la RAM. ¿Pero los registros? ¿Se almacenan en el procesador?
  • Dices que el LR sirve para que el bl sepa a dónde volver. Entonces, supongo que si haces que vaya a otra rutina mediante el bl, esa rutina deberá usar el registro LR, ¿no? ¿Qué pasa si lo quito? ¿No retorna a ningún sitio?
  • No entiendo para qué tendría que usar el PC. O sea, ¿de qué nos sirve saber cuál rutina se va a ejecutar siguiente? Además, dices que al hacer un bl, el valor del PC se guardaría en el LR. ¿Pero el LR no almacena la rutina anterior?
  • Igual me estoy liando, pero tenía entendido que había que hacer callasm 0x(offset de la rutina .asm +1).
  • ¿Cuál compilador estáis usando?

¡Muchas gracias! :D
 

Kaiser de Emperana

Called in hand
Respuesta: Re: Clase 1

Sé que las variables se almacenan en la RAM. ¿Pero los registros? ¿Se almacenan en el procesador?
Precisamente.

Dices que el LR sirve para que el bl sepa a dónde volver. Entonces, supongo que si haces que vaya a otra rutina mediante el bl, esa rutina deberá usar el registro LR, ¿no? ¿Qué pasa si lo quito? ¿No retorna a ningún sitio?
Al ejecutar la instrucción bl, automáticamente el valor del registro lr cambia por el offset en donde se encuentra la instrucción posterior al bl. Por eso es que si hacés algo como desechar el valor del lr, en la mayoría de los casos (a no ser que hagas algo raro) vas a buguear el juego.
La razón por la que la mayoría de las rutinas empiezan con un "push {lr}" es porque en caso de ejecutarse un bl dentro de la misma, el valor del lr se perdería, por lo que, antes, es guardado en el stack.

No entiendo para qué tendría que usar el PC. O sea, ¿de qué nos sirve saber cuál rutina se va a ejecutar siguiente? Además, dices que al hacer un bl, el valor del PC se guardaría en el LR. ¿Pero el LR no almacena la rutina anterior?
A vos no te sirve de nada, al que SÍ le sirve es al procesador, que sabe que instrucción tiene que ejecutar después. Mientras se ejecuta el bl, el valor del pc tiene el offset que apunta a la próxima instrucción a ser ejecutada (como lo dije en tu duda anterior). Luego de ejecutar el bl, el valor del pc va a cambiar al del offset de la rutina que le dice el bl; de esta forma, el procesador va a pasar a ejecutar las instrucciones de una subrutina, mientras guarda un puntero de a dónde tiene que regresar en el lr.

Igual me estoy liando, pero tenía entendido que había que hacer callasm 0x(offset de la rutina .asm +1).
Sí, es +1.
(Extensión de la respuesta cuya única función práctica es confundirte más: En esta escuela vamos a ver el set de instrucciones de 16bits de ASM para procesadores ARM, llamado thumb. Cada vez que quieras ejecutar una rutina en thumb vas a tener que ponerle un +1.
Pero también se pueden programar rutinas con el set de instrucciones de 32bits, llamado ARM. Para ejecutar una rutina en ARM no se debe poner el +1.)


¿Cuál compilador estáis usando?
Ensamblador, no compilador.
No estoy seguro de que version, pero está usando la toolchain de GNU, para al arquitectura ARM. Si te interesa la versión exacta que usa todo el mundo con ese .bat de Hackme, podés ejecutar "as -v" desde el cmd.
 

Asmodeo Leviatan

¿La Iglesia inventó el Infierno? O es lo contrario
wojojo!! ya se como compilar rutinas ASM!!!!
tanto me hacia fata aprender eso :3 espero poder estar para cuando este la tarea, pero una pregunta, la rutina compilada se puede meter en un espacio vacio como los


FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF XD FF FF FF?
 

MetalKaktus

A la luz del quinto día, mira al este
Miembro insignia
@Laquin solo quiero añadir una cosa que se le ha pasado por alto a @Monika explicarte. Y es que lo que tu insertas en la ROM no es el archivo .asm sino la rutina ya compilada. Es decir, el archivo .bin. Y no te preocupes, en la próxima clase ya os dejaré una carpeta con el compilador (entre otras cosas).

@axel jose guerra es que lo que está lleno de FF es espacio vacío. Es ahí donde debes insertar la rutina para no sobreescribir nada importante.
 

Ancer

Usuario de oro
2 cosas

• y es que no entiendo muy bien el orden de que se utiliza el bl y lr?
No estoy seguro a que se referían :p
•lo mismo pero en caso de pc @Monika decías que era para que el procesador supiera lo que sigue pero como
Lo que sigue en la misma rutina o cuando regrese o_O

Si estoy confundido en eso y quisiera saberlo o tener una idea mas clara porfa
 

MetalKaktus

A la luz del quinto día, mira al este
Miembro insignia
Re: Respuesta: Clase 1

2 cosas

• y es que no entiendo muy bien el orden de que se utiliza el bl y lr?
No estoy seguro a que se referían :p
•lo mismo pero en caso de pc @Monika decías que era para que el procesador supiera lo que sigue pero como
Lo que sigue en la misma rutina o cuando regrese o_O

Si estoy confundido en eso y quisiera saberlo o tener una idea mas clara porfa
Es que el bl es un comando y el lr es un registro. Son dos cosas diferentes. A ver, un bl es un comando que hace que se salte a otro offset, y para recordar a donde hay que volver, el valor de pc hace un backup de su valor en lr, puesto que una vez hecho el salto el valor de pc se modificará. Esto lo veras mejor en la próxima clase no te preocupes.

Respecto a lo otro, el pc sirve para saber cual es la próxima rutina o comando. Es así de sencillo.
 

~Lukhi

El tipo que a veces comenta en tu post.
Genial, primera clase. Tengo una dudas que me gustaría aclarar, sobretodo con lo de compilar una rutina. Mi duda es la siguiente:
-¿Por que el offset solo puede terminar en 0, 4, 8 o C?
-¿En que parte especifica del script debo ocupar el comando callasm?

Gracias por ponerle tanta dedicación a la clase. Estoy seguro de que así aprenderé rápido ASM.
 

Kaiser de Emperana

Called in hand
Respuesta: Re: Clase 1

-¿Por que el offset solo puede terminar en 0, 4, 8 o C?
Porque el procesador de la gba es de 32bits, es decir, 4 bytes, lo que quiere decir que cuando quiere leer un número escrito en la rom, puede leer números de un tamaño de hasta 4 bytes. Pero tiene la limitación de que sólo puede hacer eso cuando ese número está escrito en un offset que sea múltiplo de 4, caso contrario va a leer cualquier cosa.
Los números 0, 4, 8 y C (12 en hexadecimal) son múltiplos de 4.

-¿En que parte especifica del script debo ocupar el comando callasm?
En la parte que quieras que tu rutina se ejecute... No se si entiendo la duda xD
 

Asmodeo Leviatan

¿La Iglesia inventó el Infierno? O es lo contrario
eh hecho eh insertado una rutina como me dice aca pero no se hacer el pointer +1... eso se dira en la proxima clase?
 

Ancer

Usuario de oro
eh hecho eh insertado una rutina como me dice aca pero no se hacer el pointer +1... eso se dira en la proxima clase?
Eso se refiere al pointer +1
Es decir si es 7f0000 entonces seria 7f0001
Si es 832784 seria 832785
Es la misma dirección en la que pusiste la rutina mas 1
Ya que no te pide que lo invierta que seria
7f0000 seria 01 00 7f
832784 seria 85 27 83

A y se poner 08 al final si es en una parte no expandida de la ROM o 09 si es una parte expandía
 

Asmodeo Leviatan

¿La Iglesia inventó el Infierno? O es lo contrario
Eso se refiere al pointer +1
Es decir si es 7f0000 entonces seria 7f0001
Si es 832784 seria 832785
Es la misma dirección en la que pusiste la rutina mas 1
Ya que no te pide que lo invierta que seria
7f0000 seria 01 00 7f
832784 seria 85 27 83

A y se poner 08 al final si es en una parte no expandida de la ROM o 09 si es una parte expandía

taduccion?? espera un momento, y si es en el offecet 71D030???
 

Asmodeo Leviatan

¿La Iglesia inventó el Infierno? O es lo contrario
arigato!!! me habeis ayudado mucho, explicas bien XD anoche antes de que respondieras por segunda vez lo ise pero aun asy no pude lograr lo que queria, gracias, que pases buen dia.
 

Gosuto

Spriter de las Tinieblas
eh hecho eh insertado una rutina como me dice aca pero no se hacer el pointer +1... eso se dira en la proxima clase?
Eso es muy sencillo simplemente sumas tu offset (donde tienes la rutina) + 1 ejemplo:

800000 + 1 = 800001

Como ves 800000 es el offset y simplemente le sumas el 1 cuando lo uses en un script

Pd: No me habia fijado que ya te habian dado la respuesta jaja
 
Última edición:

Asmodeo Leviatan

¿La Iglesia inventó el Infierno? O es lo contrario
Eso es muy sencillo simplemente sumas tu offset (donde tienes la rutina) + 1 ejemplo:

800000 + 1 = 800001

Como ves 800000 es el offset y simplemente le sumas el 1 cuando lo uses en un script

Pd: No me habia fijado que ya te habian dado la respuesta jaja

aun asy se agradece... pero ese ejemplo es muy simple XD mejor seria explicar con offecet que las personas si utilizarian (con esto me refiero a que avemos personas que trabajamos con offecet como 72D070, pero ya entenderas) en fin, gracias... tu ayuda se agradece para una persona como yo XD:blush::blush::blush:
 

Chema

Very Friendly
Muy buena lección, pero mi pregunta es la siguiente: ¿Un registro cumple la mísma función de una variable o tiene una función más compleja?
 

MetalKaktus

A la luz del quinto día, mira al este
Miembro insignia
Re: Respuesta: Clase 1

Muy buena lección, pero mi pregunta es la siguiente: ¿Un registro cumple la mísma función de una variable o tiene una función más compleja?
Dicho de forma simple, por lo que a nosotros respecta, los registros almacenan un total de cuatro bytes. Las cuales se usan como parámetros de los comandos. No tiene más misterio.
 
Estado
Cerrado para nuevas respuestas.
Arriba