Registrarse

[ASM] Clase 2 : Registro

Cheve

MoonLover~
Miembro de honor
Clase Número 2 - Registros


(Se recomienda encarecidamente haber leído con anterioridad las otras clases Número 0 y Número 1 )


¡Seguimos añadiendo conceptos y conocimiento necesario!

Como todos sabrán, (o no) quien se encarga de procesar cada línea de código ASM, es el procesador. Éste se encarga de mover información y/o datos de un lado a otro. Lo hace a través de sus Registros.

Registros:

Son memorias de alta velocidad y poca capacidad. Se usan para almacenar punteros y datos, ya sea para hacer operaciones aritméticas o lógicas.
En el procesador de la GBA, contamos con 16 registros de 32 Bytes cada uno (Hasta 0xFFFFFFFF).
Si bien en GBATEK nos hablan de varias cosas sobre ellos, destacaré las más importantes (y que usaremos)(excepto casos muy especial). Para refererime a un registro usar una R mayúscula seguida de su número (Los registros van de 0 a 15 y algunos de ellos tienen nombres especiales).
(Nosotros usaremos el Procesador siempre en Thumb Mode)


Uso general:

Se dice que un registro es de uso general cuando no es más rápido que otro en nada, no tiene un uso específico designado. (Como podría ser uno dedicado a sumar o restar, por decir un ejemplo burdo).
En otras palabras, todos los registros "de uso general" son iguales entre sí.

  • Registros bajos (Lo-Registers):
    Son los comprendidos entre el R0 y el R7, todas las instrucciones (Que veremos más adelante) pueden acceder a ellos y modificarlos a antojo del programador. Son de uso general

  • Registros altos (Hi-Registers):
    Son los comprendidos entre R8 y R12, a los que solo algunas instrucciones pueden acceder. Aún así se puede decir que también son de uso general.

Stack Pointer: (R13)
Registro 13 o SP: es el conocido como Stack Pointer, es un registro especial, ya que es el "Puntero del Stack" o "Puntero de la Pila"​

¿DE UNA PILA? Si, una "pila de punteros", es decir un puntero apilado uno sobre el otro.

Ilustremos, primero, qué es una "Pila" (Elemento muy usado en programación, (antiguamente) y que se desarrolla en carreras afines)


Pila:

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:




Bueno, en términos generales y simples así funciona una Pila (Stack).
Nuestro Stack Pointer (SP) nos marcará donde está el punto más alto de la pila que usaremos para guardar distintos valores de nuestros registros hablaremos de ésto mejor más adelante, cuando empecemos con las instrucciones.
Les recomiendo que si no han entendido como funciona una pila, vuelvan a leerlo o pregunten en un comentario es muy importante que lo entiendan.

Link Register:(LR) (R14)

Registro 14 o "Registro de Enlace" (Lo llamaremos LR): Aunque su nombre puede que les indique de que vá, no es tan obvio y se merece una explicación que yo no voy a dar éste registro almacena la dirección de regreso de un "Branch with Link" o "Salto con enlace", es decir, al saltar de líneas éste registro guarda la dirección siguiente al BL para luego poder hacer un regreso. (O lo que es lo mismo, guarda el valor del R15 - PC, que ahora veremos)
Luego de definir el R15 veréis un ejemplo de ésto combinado con el R15 para que os quede bien definidos ambos.​

Program Counter: (PC) (R15)

Registro 15 o "Contador de Programa": Éste registro lo que hace es almacenar la dirección de la próxima rutina (Es decir, lugar actual + 2 )​

Ejemplo del LR y PC combinados:

La instrucción en ejecución será la que esté marcada con Verde




Acá viene lo interesante:
Al pasar de la instrucción 102 a la 104 pasa ésto:


Bueno, éstos son todos los registros de la CPU. Si me olvido de algo sobre ellos lo pondré por aquí y a los que hallan comentado les avisaré por perfil :cool:

La próxima clase será de Instrucciones Básicas y esenciales, el uso del Stack (que no volveré a explicar, que ya estoy harto de que mi profesor me pida que lo haga xD ) y algún que otro detalle. Dejad sus comentarios y apreciaciones. Si hay algo que no entiendan ¡Pregunten! Quizá su duda sea la de alguien más también y entre todos iremos mejor :awesome:

------
Referencia a 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
 
Última edición:

Naren Jr.

Puto amo
Usuario de Platino
Respuesta: GBA | ASM | Clase Número 2: Registros, conociendo al procesador.

Ya veo, yo ultimamente estoy entrando un poco mas al tema del ASM.

Realmente esta muy bien explicado todo el comienzo de como funciona una pila y el LIFO ya conocía como funciona todo, pero no sabía que fuera implicado aquí, di una materia en la universidad que se llama sistemas operativos y explicaban como funcionan los programas en el procesador con el kernel del sistema y todo, con estas "clases" que nos estas brindando ten por seguro que mas de uno comprenderá aquellos conceptos de ASM los cuales no son nada fácil.

Tengo un profesor en la universidad y me dice que este tema de ASM es un tanto complejo pero pienso que si vamos todos aportanto y apoyando podrémos llegar muy lejos!

Saludin Chevín~
 

Tsuna-Sawada

Décimo jefe Vongola
Respuesta: GBA | ASM | Clase Número 2: Registros, conociendo al procesador.

Tengo una pequeña duda en cuanto al "Stack Pointer": Dices que cuando hay un elemento (el libro amarillo) y hay otro elemento arriba de este (libro azul), se debe sacar el elemento que esté arriba, para luego sacar el ultimo, pero qué tal si la pila está llena de elementos; se debería sacar todos para luego sacar el último? (libro amarillo)


-----------

En cuanto el tutorial está genial, muy bien explicado, por primera vez en mi vida puedo entender el ASM xD. Ojala traigas pronto el proximo tuto



Saludos :blush:
 

Laquin

Usuario mítico
Respuesta: GBA | ASM | Clase Número 2: Registros, conociendo al procesador.

Tengo una pequeña duda en cuanto al "Stack Pointer": Dices que cuando hay un elemento (el libro amarillo) y hay otro elemento arriba de este (libro azul), se debe sacar el elemento que esté arriba, para luego sacar el ultimo, pero qué tal si la pila está llena de elementos; se debería sacar todos para luego sacar el último? (libro amarillo)
Corregidme si me equivoco, pero sí. Por eso es LIFO; último en entrar, primero en salir. Así que si el libro[5] es el de arriba del todo y queremos sacar libro [3] debemos sacar también los de arriba suyo(quitamos libro[5], luego libro[4] y por último libro[3].

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

Muy buen tuto, muy bien explicado, espero el siguiente tutorialespero no sea dentro de un año :v.
Entonces si quito libro[5], libro[4] y libro[3] luego puedo meter libro[4] y libro[5]? ¿Y en qué orden entrarían?
Gracias,
¡saludos!:D
 

eing

Miembro de honor
Miembro de honor
Respuesta: GBA | ASM | Clase Número 2: Registros, conociendo al procesador.

Faltó explicar, que la "pila", estará constituida por los registros que pusheas, gracias a la función "push".

Ejemplo:
Pila 1 = R0
Pila 2 = R0,R1

Para trabajar con la primera pila, antes habré de popear (desmontar por decirlo de alguna manera) esa segunda pila POR COMPLETO.

Esto es muy últil cuando queremos realizar subrutinas y pasamos algunos valores, para trabajar en ellas, pero por una circunstancia u otra, trabajamos con más de los 8 registros principales.

Un gran ejemplo es la función "warp" del XSE, que pasa los siguientes valores:
warp 0xbanco 0xmapeado 0xwarp 0xCordenadaX 0xCordenadaY

Esto equivale a 5 registros.
Y aparte de eso, hay que cargar también los cabezales del mapa, y demás información. So.. Antes de saber a que mapa iremos, cargando todos los cabezales, pushearemos esos valores.

Y para finalizar, añadiré que los registros 8,9,10,11 y 12 son registros de I/O.
Es decir "entrada y salida", que solo permite llenarlos de información con la funcion "mov".
 

Cheve

MoonLover~
Miembro de honor
Respuesta: GBA | ASM | Clase Número 2: Registros, conociendo al procesador.

Faltó explicar, que la "pila", estará constituida por los registros que pusheas, gracias a la función "push".

Ejemplo:
Pila 1 = R0
Pila 2 = R0,R1

Para trabajar con la primera pila, antes habré de popear (desmontar por decirlo de alguna manera) esa segunda pila POR COMPLETO.

Esto es muy últil cuando queremos realizar subrutinas y pasamos algunos valores, para trabajar en ellas, pero por una circunstancia u otra, trabajamos con más de los 8 registros principales.

Un gran ejemplo es la función "warp" del XSE, que pasa los siguientes valores:
warp 0xbanco 0xmapeado 0xwarp 0xCordenadaX 0xCordenadaY

Esto equivale a 5 registros.
Y aparte de eso, hay que cargar también los cabezales del mapa, y demás información. So.. Antes de saber a que mapa iremos, cargando todos los cabezales, pushearemos esos valores.

Y para finalizar, añadiré que los registros 8,9,10,11 y 12 son registros de I/O.
Es decir "entrada y salida", que solo permite llenarlos de información con la funcion "mov".
Si, pero Push y Pop son instrucciones que las explicaré en el próximo número. Lo que dices es todo correcto, pero no veía porqué marear a la gente con cosas tan innecesarias para el nivel de recién entender qué es un registro y entender como funciona una pila general :)

@Tsuna-Sawada: Creo que te estás confundiendo.

El Stack, es la pila en sí. (El lugar donde guardamos libros) el SP o Stack pointer dice "Cual es el elemento de más arriba" (Libro azul, luego amarillo, luego nada)
@ALPVCLNR Exacto. Sobre tu duda, depende, hablando estrictamente de pila, debes guardar los libros en algun medio externo (Una variable) para luego meterlos en el orden que quieras, porque estarán fuera de la pila.
 

eing

Miembro de honor
Miembro de honor
Respuesta: GBA | ASM | Clase Número 2: Registros, conociendo al procesador.

Si, pero Push y Pop son instrucciones que las explicaré en el próximo número. Lo que dices es todo correcto, pero no veía porqué marear a la gente con cosas tan innecesarias para el nivel de recién entender qué es un registro y entender como funciona una pila general :)
Bueno, es que si hablas de registros, por cojones tienes que hablar de la pila y explicar que es pushear y popear, porque es con lo que trabajan los registros.

¿Qué por qué?
Pues porque las rutinas ASM, todas trabajan con X registros.
Y si antes de utilizar X registros no los pusheas, tal vez se te quede pillado el juego o no.
Dependiendo de si los datos que estaban utilizando antes dichos registros eran útiles o no.
No veo donde está el lio amigo..



@ALPVCLNR Exacto. Sobre tu duda, depende, hablando estrictamente de pila, debes guardar los libros en algun medio externo (Una variable) para luego meterlos en el orden que quieras, porque estarán fuera de la pila.
ERROR.
No es necesario guardar datos en ninguna variable, tu los guardas en la pila, para luego poder recuperarlos.
Es decir, tu guardas en la pila TODO lo que quieras volver a recuperar en un futuro cercano, sin tener que volver a cargar dicha ubicación de memoria.

En resumen; Se guarda en la pila toda información que quiera ser recuperada en esta rutina o subrutina. Si no se va a modificar es mejor guardarla en la ram para su posterior uso, y liberar la pila.
 
Última edición:

Cheve

MoonLover~
Miembro de honor
Respuesta: GBA | ASM | Clase Número 2: Registros, conociendo al procesador.

Bueno, es que si hablas de registros, por cojones tienes que hablar de la pila y explicar que es pushear y popear, porque es con lo que trabajan los registros.


¿Qué por qué?
Pues porque las rutinas ASM, todas trabajan con X registros.
Y si antes de utilizar X registros no los pusheas, tal vez se te quede pillado el juego o no.
Dependiendo de si los datos que estaban utilizando antes dichos registros eran útiles o no.
No veo donde está el lio amigo..
¿Te haz leido el tutorial? ¿Haz leido que lo que defino es el concepto general y abstracto de una Pila y no "Como funciona la pila en ASM de GBA"? ¿Sabes que el concepto de pila no se aplica solo a esto no?
La idea es explicar los registros, punto. La gente luego se acaba liando porque le quieren meter chorrocientos conceptos todos al mismo tiempo y no acaban entendiendo nada, el tutorial se hace engorroso y cansino y no lo lee nadie.


ERROR.
No es necesario guardar datos en ninguna variable, tu los guardas en la pila, para luego poder recuperarlos.
Es decir, tu guardas en la pila TODO lo que quieras volver a recuperar en un futuro cercano, sin tener que volver a cargar dicha ubicación de memoria.

En resumen; Se guarda en la pila toda información que quiera ser recuperada en esta rutina o subrutina. Si no se va a modificar es mejor guardarla en la ram para su posterior uso, y liberar la pila.
¿Lees? Enserio lo pregunto:

Sobre tu duda, depende, hablando estrictamente de pila, debes guardar los libros en algun medio externo (Una variable) para luego meterlos en el orden que quieras, porque estarán fuera de la pila.

No estoy hablando de la pila en el GBA ASM, estoy hablando del concepto general, abstracto de una Pila.
Ya sé lo que hace la Pila de la GBA, pero eso no es lo que pretendía enseñar aquí. Sino el concepto de una pila abstracta, general, como si trabajaras en cualquier lenguaje de programación, como si estuviaremos en la escuela y te dicen, "Mira, en programación a ésto se llama pila..."
Si no entendemos que es un pié o como funciona MENOS vamos a saber caminar...
No me digas ERROR sin antes saber de qué estoy hablando :)
 

FEL!X

ᴛᴜ ᴀᴍɪɢᴏ ᴇʟ ᴇsᴘᴀᴅᴀᴄʜíɴ
Usuario de Oro
Respuesta: GBA | ASM | Clase Número 2: Registros, conociendo al procesador.

Esto de los registros es bastante interesante; por lo que entiendo son almacenes de datos. El registro 13, el del Stack Pointer que marca el final/punto más alto de la pila; entiendo que funciona como una pila de datos y por comodidad y sencillez se apilan los datos ¿No?

En cuanto al registro 14 “registro de Enlace”, entiendo que sirve o está relacionado con la función de retorno ya que el registro guarda la dirección. A ver, te explicaré como he entendido el ejemplo para que me digas si lo he entendido bien o no:

En cuanto al ejemplo que has puesto de los registros 14 y 15 (LR y PC); entiendo que son 3 instrucciones; haciendo guardar al LR el offset 104 y preparando para el PC el 102,104,500 (aquí el salto) y 502

Por lo que entiendo el BL 0x500 es un salto a otro pointer y lo que hacemos es guardar en LR el punto de retorno (LR=0x104) cuando acaben las instrucciones después de 500.

Creo que más o menos me entero pero me gustaría que me confirmaras si voy bien encaminado o la estoy cagando totalmente. Muchísimas gracias Cheve ¡Grande!

Un abrazo:)

PD:
La próxima clase será de Instrucciones Básicas y esenciales, el uso del Stack y algún que otro detalle.
Gracias por los aportes; estaré atento a ello :D
 
Última edición:

jiangzhengwenjz

Usuario mítico
Respuesta: GBA | ASM | Clase Número 2: Registros, conociendo al procesador.

Esto de los registros es bastante interesante; por lo que entiendo son almacenes de datos. El registro 13, el del Stack Pointer que marca el final/punto más alto de la pila; entiendo que funciona como una pila de datos y por comodidad y sencillez se apilan los datos ¿No?

En cuanto al registro 14 “registro de Enlace”, entiendo que sirve o está relacionado con la función de retorno ya que el registro guarda la dirección. A ver, te explicaré como he entendido el ejemplo para que me digas si lo he entendido bien o no:

En cuanto al ejemplo que has puesto de los registros 14 y 15 (LR y PC); entiendo que son 3 instrucciones; haciendo guardar al LR el offset 104 y preparando para el PC el 102,104,500 (aquí el salto) y 502

Por lo que entiendo el BL 0x500 es un salto a otro pointer y lo que hacemos es guardar en LR el punto de retorno (LR=0x104) cuando acaben las instrucciones después de 500.

Creo que más o menos me entero pero me gustaría que me confirmaras si voy bien encaminado o la estoy cagando totalmente. Muchísimas gracias Cheve ¡Grande!

Un abrazo:)

PD: Gracias por los aportes; estaré atento a ello :D
I think I will make you feel clearer.
For the r13 (sp): I recommend you to learn it after knowing some instructions 'cuz the concept of piles is really useless and confusing:/ Nevertheless, if you know ldr, str, add and sub, it will be very easy.
For r14 (lr): Yes, bl will change the value of r14. However, as we're using the thumb mode, r14 will be the offset of the instruction "bl 0xXXXXXXX" + 5. The reason of it is because the function at 0xXXXXXXX will, at last, use an instruction to come back to the instruction after "bl 0xXXXXXXX". As a bl instruction costs 4 bytes instead of 2 bytes, the offset of the next instruction will be the offset of the instruction "bl 0xXXXXXXX" + 4. However, as I've said, we're in thumb mode, and the game always uses the opcode "bx" to return. (this opcode may change the mode between ARM & THUMB. ) Therefore, an extra 1 should be added so that it will still run in thumb mode. So it's not very hard to know that the value of lr will be changed to the offset of the instruction "bl 0xXXXXXXX" + 5. You should also know that bl 0xXXXXXXX is just a "format" and the real version is like "bl r15 +/- some value". So it will just branch to an address related with the offset of the "bl" opcode itself.
PS:
Absolutely, it will be much easier if you know the instructions and see the functions in game yourself.
 
Última edición:
Arriba