Diferencias
Muestra las diferencias entre dos versiones de la página.
Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
cursos:ensamblador:lenguaje_2 [19-01-2024 06:40] – sromero | cursos:ensamblador:lenguaje_2 [26-03-2024 08:13] (actual) – [Desplazamiento de bits] sromero | ||
---|---|---|---|
Línea 10: | Línea 10: | ||
Para poder continuar con éste y posteriores capítulos del curso será imprescindible haber comprendido y asimilado todos los conocimientos de las entregas anteriores, de modo que si no es así, recomendamos al lector que relea las entregas 1, 2 y 3, y que se asegure de comprender todos los conceptos explicados. | Para poder continuar con éste y posteriores capítulos del curso será imprescindible haber comprendido y asimilado todos los conocimientos de las entregas anteriores, de modo que si no es así, recomendamos al lector que relea las entregas 1, 2 y 3, y que se asegure de comprender todos los conceptos explicados. | ||
- | En esta entrega trataremos las operaciones con bits ('' | + | En esta entrega trataremos las operaciones con bits ('' |
No obstante, antes de pasar a hablar de las operaciones con bits finalizaremos con la descripción de las instrucciones de carga (en este caso las repetitivas), | No obstante, antes de pasar a hablar de las operaciones con bits finalizaremos con la descripción de las instrucciones de carga (en este caso las repetitivas), | ||
Línea 21: | Línea 21: | ||
Las 2 instrucciones que vamos a describir: '' | Las 2 instrucciones que vamos a describir: '' | ||
- | **ldi (Load And Increment): | + | **LDI (Load And Increment): |
* Leer el byte de la posición de memoria apuntada por el registro HL. | * Leer el byte de la posición de memoria apuntada por el registro HL. | ||
Línea 29: | Línea 29: | ||
* Decrementar BC en una unidad (BC=BC-1). | * Decrementar BC en una unidad (BC=BC-1). | ||
\\ | \\ | ||
- | **ldd (Load And Decrement): ** | + | **LDD (Load And Decrement): ** |
* Leer el byte de la posición de memoria apuntada por el registro HL. | * Leer el byte de la posición de memoria apuntada por el registro HL. | ||
* Escribir ese byte en la posición de memoria apuntada por el registro DE. | * Escribir ese byte en la posición de memoria apuntada por el registro DE. | ||
Línea 39: | Línea 39: | ||
< | < | ||
- | ldi: Copiar | + | ldi: Copiar |
DE=DE+1 | DE=DE+1 | ||
HL=HL+1 | HL=HL+1 | ||
BC=BC-1 | BC=BC-1 | ||
- | ldd: Copiar | + | ldd: Copiar |
DE=DE-1 | DE=DE-1 | ||
HL=HL-1 | HL=HL-1 | ||
Línea 65: | Línea 65: | ||
ldir = Repetir ldi hasta que BC valga 0 | ldir = Repetir ldi hasta que BC valga 0 | ||
= Repetir: | = Repetir: | ||
- | Copiar | + | Copiar |
DE=DE+1 | DE=DE+1 | ||
HL=HL+1 | HL=HL+1 | ||
Línea 73: | Línea 73: | ||
lddr = Repetir ldd hasta que BC valga 0 | lddr = Repetir ldd hasta que BC valga 0 | ||
= Repetir: | = Repetir: | ||
- | Copiar | + | Copiar |
DE=DE-1 | DE=DE-1 | ||
HL=HL-1 | HL=HL-1 | ||
Línea 237: | Línea 237: | ||
Antes de comenzar con las instrucciones de manipulación de registros y datos a nivel de bits vamos a ver una serie de instrucciones difíciles de encuadrar en futuros apartados y que pueden sernos de utilidad en nuestros programas: | Antes de comenzar con las instrucciones de manipulación de registros y datos a nivel de bits vamos a ver una serie de instrucciones difíciles de encuadrar en futuros apartados y que pueden sernos de utilidad en nuestros programas: | ||
- | * **scf: Set Carry Flag** : Esta instrucción (que no admite parámetros) pone a 1 el Carry Flag del registro F. Puede sernos útil en determinadas operaciones aritméticas. | + | * '' |
- | * **ccf: Complement Carry Flag** : Esta instrucción (que tampoco admite parámetros) invierte el estado del bit de Carry Flag: si está a 1 lo pone a 0, y viceversa. Puede servirnos para poner a 0 el carry flag mediante la combinación de scf + ccf, aunque esta misma operación se puede realizar con un simple '' | + | * '' |
- | * **nop: No OPeration** : Esta instrucción especial del microprocesador ocupa un byte en el código (opcode $00) y no efectúa ninguna operación ni afecta a ningún flag. En cambio, se toma 4 t-states (t-estados, o ciclos del procesador) para ejecutarse, debido al ciclo de fetch/ | + | * '' |
- | * **daa: Decimal Adjust Accumulator** : Esta instrucción permite realizar ajustes en los resultados de operaciones con números BCD (tras operaciones aritméticas). ¿Qué son los números en formato BCD? Es una manera de representar números en los registros (o memoria) de forma que de los 8 bits de un byte se utilizan los 4 bits del 0 al 3 para representar un número del 0 al 9 (4 bits = desde 0000 hasta 1111), y los 4 bits del bit 4 al 7 para representar otro número del 0 al 9. A los 2 números BCD juntos se les llama "Byte BCD" o " | + | * '' |
Todas estas instrucciones afectan a los flags de la siguiente manera: | Todas estas instrucciones afectan a los flags de la siguiente manera: | ||
Línea 310: | Línea 310: | ||
<code z80> | <code z80> | ||
- | SET bit, DESTINO | + | set bit, DESTINO |
</ | </ | ||
- | donde Bit es un número entre 0 (el bit menos significativo o bit 0) y 7 (el de más valor o más significativo), | + | donde Bit es un número entre 0 (el bit menos significativo o bit 0) y 7 (el de más valor o más significativo), |
<code z80> | <code z80> | ||
set 5, a ; Activar el bit 5 del registro A | set 5, a ; Activar el bit 5 del registro A | ||
set 0, h ; Activar el bit 0 del registro H | set 0, h ; Activar el bit 0 del registro H | ||
- | SET 7, [HL] ; Activar el bit 7 del dato contenido en | + | set 7, (hl) ; Activar el bit 7 del dato contenido en |
; la dirección de memoria apuntada por HL | ; la dirección de memoria apuntada por HL | ||
- | SET 1, [IX+10] ; Activar el bit 1 del dato en [IX+10] | + | set 1, (ix+10) ; Activar el bit 1 del dato en (IX+10) |
</ | </ | ||
Línea 326: | Línea 326: | ||
<code z80> | <code z80> | ||
- | RES bit, DESTINO | + | res bit, DESTINO |
res 0, h ; Desactivar el bit 0 del registro H | res 0, h ; Desactivar el bit 0 del registro H | ||
- | RES 7, [HL] ; Desactivar el bit 7 del dato contenido en | + | res 7, (hl) ; Desactivar el bit 7 del dato contenido en |
; la dirección de memoria apuntada por HL | ; la dirección de memoria apuntada por HL | ||
- | RES 1, [IX-5] ; Desactivar el bit 0 del dato en [IX-5] | + | res 1, (ix-5) ; Desactivar el bit 0 del dato en (IX-5) |
</ | </ | ||
Línea 340: | Línea 340: | ||
Instrucción | Instrucción | ||
| | ||
- | | + | |
- | | + | |
</ | </ | ||
Línea 354: | Línea 354: | ||
<code z80> | <code z80> | ||
- | BIT bit, DESTINO | + | bit bit, DESTINO |
</ | </ | ||
Línea 362: | Línea 362: | ||
<code z80> | <code z80> | ||
- | ld a, 8 | + | ld a, 8 ; A = %00001000 |
- | bit 7, a ; El flag Z vale 1 | + | bit 7, a |
- | ; porque el bit 7 es 0 | + | |
- | bit 3, a ; El flag Z vale 0 | + | bit 3, a |
- | ; porque el bit 3 no es 0 | + | |
- | ; (es 1). | + | |
</ | </ | ||
Línea 375: | Línea 375: | ||
<code z80> | <code z80> | ||
- | bit 0, a ; Que valor tiene el bit 0? | + | bit 0, a |
- | ; Ahora Z = neg del bit 0 de A. | + | |
- | jp Z es_par | + | jp z, es_par |
- | ; (si Z=1 -> salta a es_par) | + | |
- | ; ya que si Z=1, es porque el bit era 0 | + | |
</ | </ | ||
Línea 388: | Línea 388: | ||
Instrucción | Instrucción | ||
| | ||
- | | + | |
</ | </ | ||
Línea 456: | Línea 456: | ||
</ | </ | ||
- | No sólo podemos rotar registros: en general el destino de la rotación podrá ser un registro, el contenido de la dirección de memoria apuntada por [HL], o bien el contenido de la memoria apuntada por un registro índice más desplazamiento ([IX+N] o [IY+N]). Más adelante veremos la tabla de afectación de flags de esta y otras instrucciones que veremos a continuación. | + | No sólo podemos rotar registros: en general el destino de la rotación podrá ser un registro, el contenido de la dirección de memoria apuntada por (HL), o bien el contenido de la memoria apuntada por un registro índice más desplazamiento ((IX+N) o [IY+N]). Más adelante veremos la tabla de afectación de flags de esta y otras instrucciones que veremos a continuación. |
Además de '' | Además de '' | ||
Línea 482: | Línea 482: | ||
<code z80> | <code z80> | ||
- | scf ; Set Carry Flag (hace C=1) | + | scf ; Set Carry Flag (hace C=1) |
- | ld b, %00000010 | + | ld b, %00000010 |
- | rl b | + | rl b |
- | scf ; Set Carry Flag (hace C=1) | + | scf ; Set Carry Flag (hace C=1) |
- | ld b, %01000001 | + | ld b, %01000001 |
- | rr b | + | rr b |
</ | </ | ||
- | Así pues, RLC y RRC son circulares y no utilizan el Carry Flag, mientras que '' | + | Así pues, '' |
+ | |||
+ | Utilizando '' | ||
Veamos la tabla de afectación de flags de estas nuevas instrucciones: | Veamos la tabla de afectación de flags de estas nuevas instrucciones: | ||
Línea 499: | Línea 501: | ||
Instrucción | Instrucción | ||
| | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
</ | </ | ||
Línea 779: | Línea 781: | ||
\\ | \\ | ||
- | | + | No existe una instrucción oficial '' |
+ | |||
+ | Finalmente, se da la curiosidad de que existe una serie de opcodes que no están documentados en el manual de Z80 y que dan lugar a una operación de desplazamiento nueva llamada '' | ||
<code z80> | <code z80> | ||
- | sll r | + | sli r |
- | sll (hl) | + | sli (hl) |
- | sll (ix+d) | + | sli (ix+d) |
- | sll (iy+d) | + | sli (iy+d) |
</ | </ | ||
Línea 792: | Línea 796: | ||
< | < | ||
Bit 7 6 5 4 3 2 1 0 C 7 6 5 4 3 2 1 0 | Bit 7 6 5 4 3 2 1 0 C 7 6 5 4 3 2 1 0 | ||
- | ----------------- -> SLL -> ------------------------ | + | ----------------- -> SLI -> ------------------------ |
a b c d e f g h a b c d e f g h 1 | a b c d e f g h a b c d e f g h 1 | ||
</ | </ | ||
Línea 801: | Línea 805: | ||
Flags | Flags | ||
Instrucción | Instrucción | ||
- | | + | ------------------------------------------------------------------------------ |
- | SLA s |* * 0 P 0 *| Shift Left Arithmetic (s=s*2) | + | SLA s |* * 0 P 0 *| Shift Left Arithmetic (s = s<< |
- | SRA s |* * 0 P 0 *| Shift Right Arithmetic (s=s/2) | + | SRA s |* * 0 P 0 *| Shift Right Arithmetic (s = s/2) |
- | SRL s |* * 0 P 0 *| Shift Right Logical (s=s>> | + | SRL s |* * 0 P 0 *| Shift Right Logical (s = s>> |
- | | + | |
</ | </ | ||
Línea 833: | Línea 837: | ||
<code z80> | <code z80> | ||
- | | + | sla e |
- | rl d | + | rl d |
</ | </ | ||
Línea 890: | Línea 894: | ||
<code z80> | <code z80> | ||
ld ix, 16384 | ld ix, 16384 | ||
- | SLA (IX) | + | sla (ix) |
- | RL (IX+01H) | + | rl (ix+$01) |
</ | </ | ||
Línea 920: | Línea 924: | ||
------------- | ------------- | ||
|* * 0 P 0 *|</ | |* * 0 P 0 *|</ | ||
- | | **rlca** | **Rotate Left Circular Accumulator**\\ Rota el registro A en un bit a la izquierda.\\ Igual que **RLC** pero con diferente afectación de Flags.\\ El CF no entra en el registro.\\ El CF se ve afectado: CF = copia del bit 7 | < | + | | **RLCA** | **Rotate Left Circular Accumulator**\\ Rota el registro A en un bit a la izquierda.\\ Igual que **RLC** pero con diferente afectación de Flags.\\ El CF no entra en el registro.\\ El CF se ve afectado: CF = copia del bit 7 | < |
---------------------- | ---------------------- | ||
| | ||
------------- | ------------- | ||
|- - 0 - 0 *|</ | |- - 0 - 0 *|</ | ||
- | | **rrca** | **Rotate Right Circular Accumulator**\\ Rota el registro A en un bit a la derecha.\\ Igual que **RRC** pero con diferente afectación de Flags.\\ No interviene el CF. \\ El CF se ve afectado: CF = copia del bit 0 | < | + | | **RRCA** | **Rotate Right Circular Accumulator**\\ Rota el registro A en un bit a la derecha.\\ Igual que **RRC** pero con diferente afectación de Flags.\\ No interviene el CF. \\ El CF se ve afectado: CF = copia del bit 0 | < |
---------------------- | ---------------------- | ||
| | ||
------------- | ------------- | ||
|- - 0 - 0 *|</ | |- - 0 - 0 *|</ | ||
- | | **rla** | **Rotate Left Accumulator**\\ Rota el registro Aen un bit a la izquierda.\\ Igual que **RL** pero con diferente afectación de Flags.\\ El CF es un bit más (el 8) del registro.\\ Inserta el CF en el bit 0.\\ El CF se ve afectado: CF = valor del bit 7 | < | + | | **RLA** | **Rotate Left Accumulator**\\ Rota el registro Aen un bit a la izquierda.\\ Igual que **RL** pero con diferente afectación de Flags.\\ El CF es un bit más (el 8) del registro.\\ Inserta el CF en el bit 0.\\ El CF se ve afectado: CF = valor del bit 7 | < |
---------------------- | ---------------------- | ||
| | ||
------------- | ------------- | ||
|- - 0 - 0 *|</ | |- - 0 - 0 *|</ | ||
- | | **rra** | **Rotate Right Accumulator**\\ Rota el registro A en un bit a la derecha.\\ Igual que **RR** pero con diferente afectación de Flags.\\ El CF es un bit más (el 8) del registro.\\ Inserta el CF en el bit 0. \\ El CF se ve afectado: CF = valor del bit 0 | < | + | | **RRA** | **Rotate Right Accumulator**\\ Rota el registro A en un bit a la derecha.\\ Igual que **RR** pero con diferente afectación de Flags.\\ El CF es un bit más (el 8) del registro.\\ Inserta el CF en el bit 0. \\ El CF se ve afectado: CF = valor del bit 0 | < |
---------------------- | ---------------------- | ||
| | ||
Línea 955: | Línea 959: | ||
------------- | ------------- | ||
|* * 0 P 0 *|</ | |* * 0 P 0 *|</ | ||
- | | **SLL** | **Shift Left Logical**\\ Desplaza el registro o dato en un bit a la izquierda.\\ Introduce un 1 por la derecha (bit 0).\\ El bit saliente (bit 7) se copia al CF. | < | + | | **SLI** | **Shift Left And Increment**\\ Desplaza el registro o dato en un bit a la izquierda.\\ Introduce un 1 por la derecha (bit 0).\\ El bit saliente (bit 7) se copia al CF. | < |
---------------------- | ---------------------- | ||
- | | + | |
------------- | ------------- | ||
|* * 0 P 0 *|</ | |* * 0 P 0 *|</ | ||
Línea 1014: | Línea 1018: | ||
rrd |* * 0 P 0 -| | rrd |* * 0 P 0 -| | ||
</ | </ | ||
+ | |||
+ | A continuación podemos ver un resumen gráfico de las diferentes instrucciones de desplazamiento obtenido del libro "// | ||
+ | |||
+ | \\ | ||
+ | {{ : | ||
+ | \\ | ||
\\ | \\ | ||
Línea 1062: | Línea 1072: | ||
<code z80> | <code z80> | ||
- | AND ORIGEN | + | and ORIGEN |
- | OR ORIGEN | + | or ORIGEN |
- | XOR ORIGEN | + | xor ORIGEN |
</ | </ | ||
- | Donde '' | + | Donde '' |
La operación '' | La operación '' | ||
Línea 1076: | Línea 1086: | ||
and b | and b | ||
or c | or c | ||
- | OR [HL] | + | or (hl) |
- | XOR [IX+10] | + | xor (ix+10) |
and 45 | and 45 | ||
</ | </ | ||
Línea 1185: | Línea 1195: | ||
Instrucción | Instrucción | ||
| | ||
- | | + | |
- | | + | |
- | | + | |
</ | </ | ||
Línea 1204: | Línea 1214: | ||
<code z80> | <code z80> | ||
and %10000000 | and %10000000 | ||
- | jp NZ bit_7_activo | + | jp nz, bit_7_activo |
</ | </ | ||
Línea 1212: | Línea 1222: | ||
< | < | ||
- | xor a | + | xor a => ld a, 0 |
</ | </ | ||