Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa |
cursos:ensamblador:arquitectura [19-01-2024 06:24] – [Opcodes y código máquina] sromero | cursos:ensamblador:arquitectura [20-01-2024 20:11] (actual) – [Partes del mapa de Memoria del Spectrum] sromero |
---|
| |
En un modelo 48K, encontraremos después de $6000 mucha más RAM. Aparte de los 8KB entre $6000 y $7fff, tenemos otros 2 bloques de 16KB (un total de 32KB más) de $8000 (32768) a $bfff (49151) y de $c000 (49152) a $ffff (65535). | En un modelo 48K, encontraremos después de $6000 mucha más RAM. Aparte de los 8KB entre $6000 y $7fff, tenemos otros 2 bloques de 16KB (un total de 32KB más) de $8000 (32768) a $bfff (49151) y de $c000 (49152) a $ffff (65535). |
| |
| La siguiente figura, extraída del libro "//Sprites y Graficos En Lenguaje Maquina//" (de //John Durst//), muestra un esquema del mapa de memoria del Spectrum 48K: |
| |
| \\ |
| {{ :cursos:ensamblador:mapa-mem-sprites-y-graficos-lenguajemaquina.jpg }} |
| \\ |
| |
\\ | \\ |
o Ejecutar la instrucción | o Ejecutar la instrucción |
Fin Mientras | Fin Mientras |
| |
</code> | </code> |
| |
* Leer el byte contenido en la dirección de memoria "PC" (40000). | * Leer el byte contenido en la dirección de memoria "PC" (40000). |
* Incrementar PC (PC=PC+1). | * Incrementar PC (PC=PC+1). |
* El byte es **$3e**, con lo cual el Spectrum sabe que el opcode | * El byte es "$3e", con lo cual el Spectrum sabe que el opcode |
la instrucción es un "ld a, valor", y que por tanto tiene | la instrucción es un "ld a, valor", y que por tanto tiene |
que meter en A un valor numérico. | que meter en A un valor numérico. |
* La primera parte leída de la instrucción es el OPCODE (código de operación), y es lo que permite al Spectrum, mediante una "tabla interna", saber qué tarea exacta tiene que realizar. Si la instrucción necesita datos extra para leer de memoria, se almacenan tras el opcode, y se conocen como "operandos". Así, ''ld a, 00'' se corresponde con la instrucción **$3e $00**, donde **$3e** es el código de operación (opcode) y **$00** es el operando. | * La primera parte leída de la instrucción es el OPCODE (código de operación), y es lo que permite al Spectrum, mediante una "tabla interna", saber qué tarea exacta tiene que realizar. Si la instrucción necesita datos extra para leer de memoria, se almacenan tras el opcode, y se conocen como "operandos". Así, ''ld a, 00'' se corresponde con la instrucción **$3e $00**, donde **$3e** es el código de operación (opcode) y **$00** es el operando. |
| |
* Para el Spectrum, no hay diferencia entre instrucciones y datos. Un **$3c** puede ser un ''inc a'' o un valor númerico **$3c** como parte de una cadena de texto, o de un gráfico, o un operador (el valor que queremos meter en un registro). ¿Cómo distingue el Spectrum uno de otro? Sencillo: todo depende de si se encuentra al principio de un ciclo de decodificación o no. Es decir, si cuando vamos a empezar a leer una instrucción leemos un "$3c", es un ''inc a''. Pero si lo leemos en el proceso de lectura de un operando, su significado cambia. Pensad en por ejemplo en ''ld a, $3c'', que se codificaría como **$3e $3c**, pero no ejecutaría un ''inc a'' porque la lectura del **$3c** se realiza como operando para el ''ld a,''. | * Para el Spectrum, no hay diferencia entre instrucciones y datos. Un **$3c** puede ser un ''inc a'' o un valor númerico **$3c** como parte de una cadena de texto, o de un gráfico, o un operador (el valor que queremos meter en un registro). ¿Cómo distingue el Spectrum uno de otro? Sencillo: todo depende de si se encuentra al principio de un ciclo de decodificación o no. Es decir, si cuando vamos a empezar a leer una instrucción, cuando estamos leyendo el opcode de la misma, leemos un **$3c**, es un ''inc a''. Pero si lo leemos en el proceso de lectura de un operando, su significado cambia. Pensad en por ejemplo en ''ld a, $3c'', que se codificaría como **$3e $3c**, pero no ejecutaría un ''inc a'' porque la lectura del **$3c** se realiza como operando para el ''ld a,''. |
| |
* Al no existir diferencia entre instrucciones y datos, si cambiamos PC de forma que apunte a una zona de la memoria donde hay datos y no código, el Z80 tratará de interpretar los números que va leyendo como si fueran opcodes (con resultados imprecedibles, seguramente con el cuelgue del Spectrum o un reset). | * Al no existir diferencia entre instrucciones y datos, si cambiamos PC de forma que apunte a una zona de la memoria donde hay datos y no código, el Z80 tratará de interpretar los números que va leyendo como si fueran opcodes (con resultados imprecedibles, seguramente con el cuelgue del Spectrum o un reset). |
| 50003 | $c9 | | | 50003 | $c9 | |
| |
Si ahora saltamos a la dirección 50000 para ejecutar el programa, lo primero que encuentra el procesador es $21, que indica al procesador que la instrucción es un ''ld hl,'' y que el valor a cargar en HL viene en memoria a continuación en las 2 siguientes celdillas de memoria. Pero al ser un procesador little-endian, no nos encontramos primero $40 y luego $00 (como en el $4000 que nosotros tecleamos en nuestro programa ensamblador) sino que en memoria está almacenado al revés: $00 primero y $40 en el byte siguiente. Cuando el procesador haya terminado de leer los 3 bytes y ejecute la instrucción, el registro HL contendrá el valor $4000 (no $0040, ya que el orden de aparición sólo es una cuestión de orden de almacenamiento). | Si ahora saltamos a la dirección 50000 para ejecutar el programa, lo primero que encuentra el procesador es $21, que indica al procesador que la instrucción es un ''ld hl,'' y que el valor a cargar en HL viene en memoria a continuación en las 2 siguientes celdillas de memoria. Pero al ser un procesador little-endian, no nos encontramos primero **$40** y luego **$00** (como en el **$4000** que nosotros tecleamos en nuestro programa ensamblador) sino que en memoria está almacenado al revés: **$00** primero y **$40** en el byte siguiente. Cuando el procesador haya terminado de leer los 3 bytes y ejecute la instrucción, el registro HL contendrá el valor $4000 (no $0040, ya que el orden de aparición sólo es una cuestión de orden de almacenamiento). |
| |
Esto no sólo ocurre con las instrucciones ensambladas, sino que ocurre lo mismo con los datos de 16 bits almacenados en memoria. Si ejecutamos: | Esto no sólo ocurre con las instrucciones ensambladas, sino que ocurre lo mismo con los datos de 16 bits almacenados en memoria. Si ejecutamos: |
</code> | </code> |
| |
Si revisamos los valores almacenados en memoria, encontraremos el valor $34 en $4000 y el valor $12 en $4001. | Si revisamos los valores almacenados en memoria, encontraremos el valor **$34** en **$4000** y el valor **$12** en **$4001**. |
| |
Y si después hacemos: | Y si después hacemos: |