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Última revisiónAmbos lados, revisión siguiente | ||
cursos:ensamblador:habituales [24-01-2024 17:36] – [Optimizaciones habituales] sromero | cursos:ensamblador:habituales [02-02-2024 18:34] – [Comparaciones de 8 bits] sromero | ||
---|---|---|---|
Línea 5: | Línea 5: | ||
Por ejemplo, las comparaciones de 8 y 16 bits son básicas y tendremos que usarlas decenas (sino cientos) de veces a lo largo de nuestro programa para implementar la lógica no sólo de bucles sino también de condiciones como "// | Por ejemplo, las comparaciones de 8 y 16 bits son básicas y tendremos que usarlas decenas (sino cientos) de veces a lo largo de nuestro programa para implementar la lógica no sólo de bucles sino también de condiciones como "// | ||
- | También veremos construcciones u optimizaciones habituales en ensamblador, | + | También veremos construcciones u optimizaciones habituales en ensamblador, |
Línea 11: | Línea 11: | ||
===== Comparaciones de 8 bits ===== | ===== Comparaciones de 8 bits ===== | ||
- | Las comparaciones de valores 8 bits son situaciones extremadamente habituales en nuestros programas. En múltiples ocasiones tendremos que verificar si el valor de un determinado registro es igual, distingo, menor, mayor, menor igual o mayor igual que el valor de otro registro o que un valor inmediato. | + | Las comparaciones de valores |
Como ya vimos en el capítulo dedicado a las instrucciones básicas, las comparaciones se basan en **restas** ('' | Como ya vimos en el capítulo dedicado a las instrucciones básicas, las comparaciones se basan en **restas** ('' | ||
Línea 36: | Línea 36: | ||
\\ | \\ | ||
- | Así, tras un '' | + | Así, tras un '' |
\\ | \\ | ||
- | * **A == N** (A igual n): Si se activa **ZF** (flag de Zero), es porque el resultado de la resta es 0, es decir, A < n son iguales. | + | * **A == N** (A igual n): Si se activa **ZF** (flag de Zero), es porque el resultado de la resta es 0, es decir, A y N son iguales. |
* **A != n** (A distinto de n): Si no se activa **ZF** (flag de Zero), es porque el resultado de la resta no es 0, es decir A y n son diferentes. | * **A != n** (A distinto de n): Si no se activa **ZF** (flag de Zero), es porque el resultado de la resta no es 0, es decir A y n son diferentes. | ||
- | * **A < n** (A menor que n): Si no era igual, y se activa **CF** (flag de Carry), es porque el resultado de la resta es negativo, es decir, A es menor que B. | + | * **A < n** (A menor que n): Si no era igual, y se activa **CF** (flag de Carry), es porque el resultado de la resta es negativo, es decir, A es menor que B. No es necesario comprobar primero el valor del ZF, si CF está activo, entonces A es menor que N, siempre. |
* **A > n** (mayor que): Si no era igual, y no se activa **CF** (flag de Carry), es porque el resultado de la resta es positivo, es decir, A es mayor que B. | * **A > n** (mayor que): Si no era igual, y no se activa **CF** (flag de Carry), es porque el resultado de la resta es positivo, es decir, A es mayor que B. | ||
Línea 50: | Línea 50: | ||
\\ | \\ | ||
- | La igualdad requiere sólo verificar el flag de Zero, mientras | + | La igualdad requiere sólo verificar el flag de Zero, la comparación " |
< | < | ||
Línea 57: | Línea 57: | ||
= | = | ||
!= => Z=0 | != => Z=0 | ||
- | < | + | < |
> | > | ||
<= => Z=1, C=1 | <= => Z=1, C=1 | ||
Línea 74: | Línea 74: | ||
</ | </ | ||
- | Veamos ejemplos de código, comparando A con 50 (podemos usar para los saltos tanto '' | + | Veamos ejemplos de código, comparando A con 50 (podemos usar para los saltos tanto '' |
- | Para comparar si **A == 50**, simplemente comprobamos ZF: | + | Para comparar si **A == 50** o si **A != 50**, simplemente comprobamos ZF: |
<code z80> | <code z80> | ||
Línea 89: | Línea 89: | ||
; igual a 50 | ; igual a 50 | ||
; (... codigo para caso a == 50 ...) | ; (... codigo para caso a == 50 ...) | ||
- | |||
- | fin_comparacion: | ||
- | </ | ||
- | |||
- | Para comparar si **A != 50**, de nuevo comprobamos ZF: | ||
- | |||
- | <code z80> | ||
- | cp 50 | ||
- | jr z, distinto_de_50 | ||
- | |||
- | ; igual a 50 | ||
- | ; (... codigo para caso a == 50 ...) | ||
- | jr fin_comparacion | ||
- | |||
- | distinto_a_50: | ||
- | ; (... codigo para caso a != 50 ...) | ||
fin_comparacion: | fin_comparacion: | ||
Línea 144: | Línea 128: | ||
<code z80> | <code z80> | ||
cp 50 | cp 50 | ||
- | jp nc, menor_o_igual_que_50 | + | jp c, menor_que_50 |
- | jp nz, menor_o_igual_que_50 | + | jp nz, menor_o_igual_que_50 |
; Ahora o es ' | ; Ahora o es ' | ||
Línea 152: | Línea 136: | ||
jr fin_comparacion | jr fin_comparacion | ||
+ | menor_que_50: | ||
menor_o_igual_que_50: | menor_o_igual_que_50: | ||
; (... codigo para caso a <= 50 ...) | ; (... codigo para caso a <= 50 ...) | ||
Línea 165: | Línea 150: | ||
; saltaría con >=51 es decir, con >50 | ; saltaría con >=51 es decir, con >50 | ||
cp 50+1 | cp 50+1 | ||
- | jp nc, mayor_O_IGUAL_que_51 | + | jp nc, mayor_que_50 |
- | ; aqui A < 50 | + | ; aqui A <= 50 |
jr fin_comparacion | jr fin_comparacion | ||
mayor_que_50: | mayor_que_50: | ||
- | | + | |
fin_comparacion: | fin_comparacion: | ||
Línea 178: | Línea 163: | ||
<code z80> | <code z80> | ||
; comparamos con valor -1 y entonces sí que podemos hacer JP C | ; comparamos con valor -1 y entonces sí que podemos hacer JP C | ||
- | ; y comprobar "mayor_que_50" mediante " | + | ; y comprobar "menor_que_50" mediante " |
; saltaría con <=49 es decir, con <50 | ; saltaría con <=49 es decir, con <50 | ||
cp 50-1 | cp 50-1 | ||
jp c, menor_igual_que_49 | jp c, menor_igual_que_49 | ||
- | ; aqui A >= 50 | + | ; aqui A > 50 |
jr fin_comparacion | jr fin_comparacion | ||
- | mayor_o_igual_que_49: | + | menor_igual_que_49: |
; aqui A <= 49 y por tanto A < 50 | ; aqui A <= 49 y por tanto A < 50 | ||
fin_comparacion: | fin_comparacion: | ||
</ | </ | ||
- | |||
Recordamos que '' | Recordamos que '' | ||
Línea 306: | Línea 290: | ||
* Si **HL > DE** => Z=0 y C=0. | * Si **HL > DE** => Z=0 y C=0. | ||
- | De la misma forma, podemos realizar rutinas específicas para compara | + | De la misma forma, podemos realizar rutinas específicas para comparar |
<code z80> | <code z80> | ||
Línea 368: | Línea 352: | ||
\\ | \\ | ||
**Resetear el Carry Flag** | **Resetear el Carry Flag** | ||
+ | |||
+ | No existe una instrucción para poner el Carry Flag a 0, aunque sí una para ponerlo a 1, y una para complementarlo. Esto permite ponerlo a 0 usando 2 instrucciones (2 bytes) y 8 t-estados. Sin embargo, es más fácil hacerlo usando cualquier operación lógica que lo resetee, como '' | ||
<code z80> | <code z80> | ||
Línea 493: | Línea 479: | ||
; Óptimo: | ; Óptimo: | ||
+ | rrca | ||
rrca | rrca | ||
rrca | rrca | ||
Línea 591: | Línea 578: | ||
; Con bit 0: | ; Con bit 0: | ||
rra ; 1 byte, 4 t-estados | rra ; 1 byte, 4 t-estados | ||
- | jr z, destino | + | jr c, destino |
; Con bit 7: | ; Con bit 7: | ||
- | rla ; | + | rla ; |
- | call z, destino | + | call c, destino |
</ | </ | ||