Domina la memoria en ensamblador: pila, datos estáticos y arrays explicados al detalle

แชร์
ฝัง
  • เผยแพร่เมื่อ 31 ก.ค. 2024
  • Curso: bit.ly/Z80GameDev-2022-Curso
    ==== Sesión 4.2 - 27/sep/22 ====
    En esta sesión profundizamos en los fundamentos de la memoria RAM y su uso. Desmitificamos la creación y destrucción de la memoria, enfatizando que somos nosotros, los programadores, quienes controlamos y manipulamos los 64Ks disponibles. Discutimos en detalle cómo dibujar una entidad (representada por un cuadrado), un ejercicio aparentemente simple que nos permite explorar y manipular los arrays en la memoria.
    Prestamos una atención particular a la pila (Stack), al Stack Pointer (SP) y su funcionamiento concreto. Nos adentramos en su localización, cómo se puede reubicar y cómo usamos SP para guardar datos esenciales de la entidad. Del mismo modo, reflexionamos sobre las diferentes formas de almacenar datos en la RAM y los registros, proporcionando una mejor comprensión de las rutinas y estructuras en el ensamblador. Apreciamos la importancia del manejo correcto de la pila, incluyendo detalles como el orden Little Endian y el uso de instrucciones como PUSH y POP.
    Exploramos conceptos más avanzados como los símbolos y los datos estáticos, que permanecen durante toda la ejecución del juego. Observamos cómo se pueden utilizar para variar nuestra técnica de dibujar la entidad. Al mismo tiempo, comprendemos qué significa usar la directiva .DS para “reservar” memoria, aclarando los malentendidos y errores comunes que se cometen al usarla y entenderla. Entendemos que un array son elementos del mismo tamaño consecutivos en memoria (sin dejar huecos). Discutimos las reglas y limitaciones de los arrays como estructura de datos, para entender mejor cómo funcionan, sus ventajas e inconvenientes.
    Comparamos los arrays en C y en ensamblador, profundizando en la relación entre los lenguajes de programación de alto y bajo nivel. Exploramos cómo podemos utilizar los datos de formas diversas, incluyendo la lectura de porciones de memoria que se sabe que están libres. Aprendemos sobre la eficiencia y reducción de la repetición en el código mediante el uso de macros y los registros HL, IX e IY.
    Finalmente, repasamos las instrucciones LDI y LDIR, destacando sus usos y beneficios en ensamblador Z80. A lo largo del la sesión, discutimos conceptos avanzados de programación, desafiamos los mitos comunes y proporcionamos una base sólida para una comprensión profunda de la programación en ensamblador. Esta sesión es una herramienta esencial para que puedas mejorar tu conocimiento y dominio de la programación a bajo nivel.
    ==== Contenidos ====
    0:00:00 Mitos desacreditados: La memoria ni se crea ni se destruye, siempre está disponible
    0:05:00 Arrays: Manipulación de entidades y uso creativo de memoria
    0:08:45 Stack Pointer (SP): Ubicación, función y reubicación
    0:24:00 Uso estratégico de SP para almacenar datos esenciales de la entidad
    0:36:50 Datos estáticos: ¿Qué son y por qué conviene usar símbolos para ubicarlos?
    0:40:00 “Reservando” memoria y aclarando conceptos con la directiva .DS
    1:04:00 Arrays en C vs Ensamblador: Comparaciones, contrastes y aplicaciones
    1:10:00 Técnicas para leer y usar porciones de memoria no utilizadas
    1:15:00 Instrucciones LDI y LDIR en profundidad: Usos y beneficios
    ==== Enlaces ====
    Máquina Virtual CPCtelera: archive.org/details/CPCtelera...
    Curso Z80-GameDev 2022: bit.ly/Z80GameDev-2022-Curso
    Más Cursos: profesorretroman.com
    ==== Agradecimientos Especiales ====
    Al equipo de profesorretroman.com :
    - Iván Fernández (@spdizzy)
    - Raúl García (@Kalandras)
    - Alfonso Carmona (@hatHus)
    Por postprocesar y editar los vídeos, elaborar descripciones y portadas.
    #GameDev #assembler #Amstrad #programming
    ==== Créditos ====
    Imágen Memoria Electrónica realizada con StableDiffusion v2.5.38
    Retoques por Ribbet AI: ribbet.ai
    Sugerencias de mejora por ChatGPT 4
    ====================
    Clase de Videojuegos 1 2022/23
    Grado en Ingeniería Multimedia
    Universidad de Alicante

ความคิดเห็น • 22

  • @xfran70
    @xfran70 หลายเดือนก่อน

    Tengo 54 años y mi primer contacto con la informática fue a los 16 años que comencé a aprender sobre microcontroladorees. Los programas en lenguaje máquina los hacía a mano y los "ejecutaba" a mano porque no tenía un hardware en el que los pudiera correr. Viendo estos videos me doy cuenta de que esta gente viene de programar en lenguajes de alto nivel en los que todo es abstraccion y todo está automatizado. Son incapaces de pensar desde el punto de vista de la cpu. Saber como funciona un microprocesador es prácticamente indispensable para entender de verdad lo que hacen las instrucciones. Como contrapartida, a mi me costó un mundo entender los lenguajes de alto nivel porque me ponía de los nervios el perder el control de la cpu y no saber exactamente lo que hacía ni como lo hacía ni donde guardaba las cosas e incluso no saber en que orden se ejecutan las instrucciones.

  • @andrewjackson508
    @andrewjackson508 ปีที่แล้ว +4

    profesor, estoy en segundo eeeeeeeee!!!!!! me quedo calculo e informatica basica, bueno , al tema , el dia que se hable del dominio de la menmoria aqui como un clavo!! gracias por todo

  • @ernestoalfonsoespinosavale1272
    @ernestoalfonsoespinosavale1272 10 หลายเดือนก่อน +2

    Llevo casi toda una carrera en esto, y con un video de aprox 1 hora he entendido mejor que en mi universidad jaja xd

  • @otrocanalmas8096
    @otrocanalmas8096 11 หลายเดือนก่อน +1

    Muy interesante.
    Pues la verdad no tengo idea de Ensamblador; pero me gusto mucho el video porque se aprende un monton.

  • @oficialbarbrady1
    @oficialbarbrady1 ปีที่แล้ว +2

    Los videos son muy buenos, de lo mejor que hay vaya. Lo importante es aprender los conceptos básicos, porque cuando programamos en lenguajes de alto nivel no sabemos muy bien lo que estamos haciendo ni cómo se está haciendo.

  • @zenhdn3580
    @zenhdn3580 ปีที่แล้ว +3

    Cada nuevo video de esta serie trae sus nuevas dosis de confianza en la implementación. Gracias eternas profe.

  • @davidsehnsucht8745
    @davidsehnsucht8745 7 หลายเดือนก่อน +1

    Todos sus videos son geniales. Sin duda de los mejores canales de youtube que existen.

  • @asudfgiasdf
    @asudfgiasdf ปีที่แล้ว +12

    Es innegable el dominio de los conceptos que tiene usted profesor y como logra transmitirlo de una manera clara. Ya me gustaría que usted fuera mi profesor. Muchas gracias por compartir estas clases. Algún libro que usted recomiende para aprender correctamente ensamblador?

    • @maurohornus9446
      @maurohornus9446 ปีที่แล้ว +1

      x 2 cualquier comentario ayuda

    • @ProfesorRetroman
      @ProfesorRetroman  ปีที่แล้ว +2

      Si es para aprender desde 0, recomiendo el "The Art of Assembly" en su 1ª edición. Lo puedes encontrar en PDF aquí: flint.cs.yale.edu/cs422/doc/art-of-asm/pdf/. El libro tiene muchos años, pero el contenido está muy bien estructurado y explica todo lo que se debe aprender desde el principio y muy bien. Después de este libro, una vez entendido y dominado, cualquier libro moderno (últimos 5 años) sobre ensamblador de 64 bits, tanto de intel como ARM, son buenas opciones.

  • @raulgarfer
    @raulgarfer ปีที่แล้ว +2

    Genial video. Como siempre, un orgullo ayudar

  • @maurohornus9446
    @maurohornus9446 ปีที่แล้ว +1

    genio

  • @codigo1x
    @codigo1x ปีที่แล้ว +1

    Genial Profe!!!

  • @Qwerty_-rz1lc
    @Qwerty_-rz1lc ปีที่แล้ว +1

    Me sorprende mucho que un canal que aporta tanto a nivel de conocimientos tenga tan pocos suscriptores, vaya pedazo de masterclass.

  • @gatita_liliana
    @gatita_liliana ปีที่แล้ว +1

    ahhhhhhhhhhh que increíble videooooooo

  • @codigo1x
    @codigo1x ปีที่แล้ว +3

    Excelente. Este video me ha abierto mucho la cabeza en cuanto al funcionameinto de la memoria en un ordenador. Consulta: Yo creía que memoria dinámica era porque se podía extender o achicar el tamaño de una zona de memoria ajustandolo a la necesidad del momento en un programa. Aquí usted explica, que es dinámica porque un mismo sector de la memoria se usa para varias cosas. El concepto que yo tenía es equivocado? O también es correcto?

    • @ProfesorRetroman
      @ProfesorRetroman  ปีที่แล้ว +3

      Pues es equivocado en fundamentos. Te explico con detalle:
      1. El término dinámico en contraposición al estático significa lo que comento en el vídeo: una misma zona de memoria se usa, a lo largo del programa, para fines diferentes. En este sentido, tanto el stack como el heap son mecanismo cómodos para gestión de uso dinámico de zonas de memoria (a veces se usan para una cosa, a veces para otra). En cambio, los datos estáticos suelen ir al segmento BSS en PC, siendo zonas de memoria destinadas al mismo uso durante toda la duración de la aplicación.
      2. Ocurre que la memoria dinámica, por naturaleza, tiene usos _temporales_. Durante un tiempo de la ejecución se requieren unos bytes en memoria para almacenar datos y, al terminar, ya no son requeridos, pudiendo ser usados para otras cosas. Esto implica que la aplicación hay instantes donde hará uso de más bytes de la memoria, y otros instantes donde hará uso de menos. Esto no sería ningún problema en un ordenador como Amstrad, donde sólo se ejecuta nuestro programa. Simplemente, nos organizamos el uso de la memoria y vamos haciendo uso a conveniencia. Sin embargo, los ordenadores modernos llevan sistemas operativos complejos que ejecutan cientos de procesos, incluso de distintos usuarios, a la vez. Esto introduce una complejidad importante: la RAM es compartida por todos los procesos. RAM sólo hay una, y tiene un tamaño fijo. Sin embargo, cada proceso va a requerir una cantidad de RAM que, además, puede variar durante su ejecución. Por este motivo, nos hacen falta mecanismos para asegurar que unos procesos no modifican la RAM de otros procesos (de hecho, que ni siquiera puedan leerla!). Por eso tenemos sistemas de reserva de RAM en los sistemas operativos modernos, a los que accedemos desde nuestros programas con llamadas a la API del Sistema Operativo. Estas llamadas son realizadas por los operadores new/delete (malloc/free) desde la librería estándar de C. Aquí lo que ocurre es que solicitamos un espacio en RAM al SO donde podamos escribir, asegurándonos de que otros procesos no pueden acceder ahí y no vamos a tener problemas. Después, tenemos la obligación de liberar ese espacio reservado, para que quede disponible para otros procesos.
      Si te fijas, el punto 2 no cambia sustancialmente respecto al punto 1. Lo que sucede es que la RAM está compartida y necesitamos más "burocracia" para hacer uso de la RAM asegurándonos de que eso no produce problemas en otros procesos. Aparte de ese punto, no es una cuestión de "dinámico porque necesito más o menos", sino, que la RAM es dinámica porque a veces la usa un proceso y a veces la usa otro. Además, incluso si la usa el mismo proceso, a veces la puede usar para una cosa, y otras veces para otra.
      Habitualmente, en las universidades, se enseña que la RAM dinámica es por temas de tamaño/necesidades. Esto genera muchísima confusión, y es lo que hace que se genere la idea de que la RAM se crea y destruye conforme lo pedimos, o que la memoria es algo que nos "dan" de alguna manera. Lo único que hacemos es usarla. La RAM está ahí. Pero, como no somos los únicos usuarios, hay que organizarse en el uso. Sería exactamente lo mismo que en el cine. Los asientos son dinámicos no porque haya más a veces o menos otras, sino porque cambia la persona que se sienta y hace uso. Los asientos siempre son los mismos en total.

    • @codigo1x
      @codigo1x ปีที่แล้ว

      @@ProfesorRetroman A ver entonces profe, mire. He escrito hace tiempo un progrma en C, al final creo que ni sé lo que he hecho jaja. Es así: Un juego donde el usuario debe memorizar una secuencia de números aleatorios que la máquina va tirando. Primero tira uno, luego dos, luego tres, etc... y el usuario repite. La cantidad de memoria que se utiliza depende de cuántos números sea capaz de memorizar la persona. Digamos que esos valores se guardan en un array dinámico que va creciendo acorde recuerdas más números de la secuencia? Por lo tanto la porción de memoria que utilizo crece?

  • @MarioDanielCarugno
    @MarioDanielCarugno 2 วันที่ผ่านมา +1

    Genioooo, muy buena clase !
    Una consulta tengo. En 52:42 se ve en la linea 65 de routines.s la instruccion: ld d, #0
    Y dice que eso esta cargando el valor 0 en el registro d
    Pero al estar precedido por # no estaria cargando el contenido de la direccion de memoria 0 en vez del valor 0 ?
    Cargar 0 en d me suena que deberia verse como: ld d, 0

    • @ProfesorRetroman
      @ProfesorRetroman  วันที่ผ่านมา +1

      Muchas gracias por tu aprecio, Mario :)
      Respecto a tu pregunta, comprendo muy bien que la almohadilla pueda resultar confusa y que te haya hecho pensar que estoy leyendo de la memoria y no un inmediato. Además, como hay muchos casos de programas ensambladores donde los números inmediatos se ponen como dices, ld d, 0, entiendo que eso añada más a la confusión. Pero, en realidad, no es más que una confusión. Te explico:
      - El código máquina es único: los bytes que describen un programa en memoria son siempre iguales para un mismo programa en Z80.
      - Sin embargo, lenguajes ensambladores hay muchos. El lenguaje ensamblador es texto que se traduce a código máquina, y la forma de traducir depende de cómo lo entiende el programa que traduce (el programa ensamblador). Como hay muchos programas ensambladores, también hay distintos lenguajes ensambladores para una misma CPU. A esto se le llaman dialectos de ensamblador.
      - Para un programa, el símbolo $ es el prefijo de números hexadecimales, para otro el prefijo es 0x. Para un programa, los corchetes [] indican que se lee de memoria, para otro, lo hacen los paréntesis (). Incluso algunas instrucciones tienen nombres o formatos ligeramente distintos entre programas ensambladores. Para tu pregunta, puede que haya algún programa ensamblador donde # sea el prefijo para indicar que se accede a memoria. Ahora mismo no conozco ninguno que use este prefijo, pero puede haberlo.
      Cosas importantes de tu pregunta:
      - No existe en Z80 una instruccion LD que cargue en el registro D directamente desde la memoria. Por tanto, una instrucción ld d, (0) ó ld d, #0, suponiendo que # significase "leer de la memoria" sería un error, porque esa instrucción, en código máquina, no existe.
      - El programa ensamblador que usamos en clase se llama ASZ80. En este ensamblador el hash # es el prefijo que indica que lo siguiente es un valor númerico inmediato. Este programa lo usa como forma rápida de distinguir inmediatos de otros valores. Por ejemplo, así se distinguen estas 2 instrucciones:
      - 1 - ld a, #(32 + 32) ;; Código máquina 3E 40
      - 2 - ld a, (32 + 32) ;; Código máquina 3A 40 00
      - La primera instrucción se traduce por cargar en el registro A el valor 64 (40 en hex), mientras que la segunda instrucción se traduce por cargar en A lo que haya en la posición 64 de la Memoria (0040 en hex, 4000 en little endian). En el primer caso, el paréntesis se interpreta como símbolo matemático (innecesario en este caso, pero puede ponerse por claridad), mientras que, en el segundo caso, es el símbolo que nos dice que vamos a acceder a memoria.
      Espero que esto te aclare la confusión :).

    • @MarioDanielCarugno
      @MarioDanielCarugno วันที่ผ่านมา +1

      @@ProfesorRetroman perfecto, entendido... muchas gracias :)

  • @LuisDiaz-uu7xg
    @LuisDiaz-uu7xg 8 หลายเดือนก่อน

    hola Fran
    de todos los videos que tienes en tu canal, dirías que este es con el que hay que empezar teniendo en cuenta que nunca he estudiado asemblador ?
    Si tienes un rato te mande un mensaje por telegram :)