Instrucciones de salto condicional

Las instrucciones de salto condicional o “branches” (bifurcaciones) son:

  • “beq” = branch on equal
  • “bne” = branch on not equal
  • “bcs” = branch on carry set
  • “bcc” = branch on carry clear
  • “bpl” = branch on plus
  • “bmi” = branch on minus
  • “bvs” = branch on overflow set
  • “bvc” = branch on overflow clear

Estas instrucciones dan un salto a la dirección indicada (en realidad usan el modo de direccionamiento relativo, es decir, un offset) cuando se cumple una determinada condición, y continúan con la siguiente instrucción cuando no se cumple. Las condiciones se basan en los flags del registro de estado.

“beq” y “bne”

Estas instrucciones se basan en el flag Z – zero. “beq” salta cuando Z está activado y “bne” cuando no lo está.

El hecho de hablar de “equal” o “not equal” viene de que, como veremos más adelante, el microprocesador realiza las comparaciones mediante una resta, lo que significa que la igualdad equivale a una resta cero, y la no igualdad a una resta distinta de cero.

“bcs” y “bcc”

Estas instrucciones se basan en el flag C – carry. “bcs” salta cuando C está activado y “bcc” cuando no lo está.

Como ya vimos, el flag C se activa cuando una suma (“adc”) desborda la capacidad del acumulador (“me llevo una”). Y se desactiva cuando una resta (“sbc”) es negativa (“tomo una”).

“bvs” y “bvc”

Estas instrucciones se basan en el flag V – overflow. “bvs” salta cuando V está activado y “bvc” cuando no lo está.

El flag V se activa cuando al sumar dos números positivos el resultado es negativo. Si se está trabajando con números con signo hay que detectar esta situación para evitar interpretar el resultado de forma incorrecta.

“bmi” y “bpl”

Estas instrucciones se basan en el flag N – negative o, lo que es lo mismo, el flag S – sign. “bmi” salta cuando N está activado y “bpl” cuando no lo está.

El flag N se activa cuando, como resultado de una instrucción, el bit de signo (bit 7) está activado.

Modos de direccionamiento y flags

Todas estas instrucciones utilizan el modo de direccionamiento relativo. Es decir, aunque el programador utilice como destino una dirección de memoria o una etiqueta (ej. “beq iguales”), el ensamblador al ensamblar sustituye esa dirección o etiqueta por un offset, es decir, un salto hacia delante o hacia atrás de N posiciones de memoria. Ese N puede oscilar entre 127 y -128 posiciones de memoria, y se cuenta respecto del primer byte de la instrucción siguiente.

Respecto a los flags, estas instrucciones no los modifican. Al contrario, y como ya se ha visto, utilizan los flags como información de entrada para determinar su funcionamiento (salto o no salto).

Los detalles de estas instrucciones pueden consultarse aquí: http://www.6502.org/tutorials/6502opcodes.html#BRA.

Otras instrucciones relacionadas

Las instrucciones de salto condicional se suelen usar conjuntamente con instrucciones de incremento/decremento y comparaciones, que se verán en las entradas que siguen. Se usan conjuntamente para implementar bucles.


Programa de ejemplo: Prog17

3 comentarios en «Instrucciones de salto condicional»

  1. Hola.

    Relacionado con los saltos condicionales, una tabla muy útil es la siguiente (A representa el acumulador y M una posición de memoria que se compara con A mediante la instrucción cmp M):

    – si A igual a M ==> salta beq
    – si A distinto de M ==> salta bne
    – si A mayor que M ==> salta bcs
    – si A menor que M ==> salta bcc
    – si A mayor o igual que M ==> salta bcs
    – si A menor o igual que M ==> bcc + beq

    Consultando esta tabla se sabe qué instrucción de salto condicional salta en qué situación o, dicho de otro modo, qué instrucción detecta qué situación.

    Yo utilizo mucho esta tabla para, en función de la situación que quiero detectar, determinar la instrucción que debo usar sin tener que darle muchas vueltas…

    Saludos.

    Me gusta

  2. Hola:
    Compre el libro para seguir completo el contenido del blog, lo he disfrutado mucho. Leí completo el libro I y avanzado algo en el II y ahora estoy mirando los códigos.

    He tenido algunos problemas con esto, si abro los ficheros que bajo directamente me da error al intentar ejecutar:
    > Closed Project ‘S:\c64\StudioProjects\TestLevel\TestLevel.cbmprj’
    > Saved Project ‘S:\c64\StudioProjects\Prog131\Prog131.cbmprj’
    >
    >
    > *** Build Started at 18:40 ***
    > Saved – S:\c64\StudioProjects\Prog131\Prog13.asm
    > Saved – S:\c64\StudioProjects\Prog131\Utils.asm
    > Saved Project ‘S:\c64\StudioProjects\Prog131\Prog131.cbmprj’
    > Preprocessing file : S:\c64\StudioProjects\Prog131\\Prog13.asm…
    > *** Pre-processor error(s) ***

    Así es que agrego los ficheros a mano y uso cortar y pegar para agregar el código, sin esto no funciona para Prog17, aparentemente existe un problema al hacer llamadas jsr a codigo contenido en otros archivos, en principio me da errores del tipo:

    Invalid operad, label or variable …. para todas las referencias a etiquetas hechas desde el archivo que contiene la rutina fuera del principal (por ejemplo flagC.asm), una vez expandidas las macros. Sin embargo si copio el código en el asm al archivo principal, (Prog7.asm) funciona sin error.

    ¿alguna idea?

    Un saludo
    Matelunga

    Me gusta

  3. Hola, Pablo.

    En el volumen 1 hice una cosa mal. Empaqueté en ZIP los ficheros *.asm de cada de ejemplo, pero en esos ficheros *.ZIP no incluí la definición del proyecto, es decir, el fichero *.cbmprj.

    Este fichero es importante porque, entre otras cosas, incluye el ORDEN en que el ensamblador debe ensamblar los ficheros *.asm. Por ejemplo, en el caso del ejemplo 17, el orden correcto es:

    <BuildList>
    <FileName>Prog17.asm</FileName>
    <FileName>Utils.asm</FileName>
    <FileName>FlagZ.asm</FileName>
    <FileName>FlagC.asm</FileName>
    <FileName>FlagV.asm</FileName>
    <FileName>FlagN.asm</FileName>
    </BuildList>

    Este orden puedes definirlo yendo el menú «Project» de CBM Prg Studio, luego a «Properties», y moviendo hacia arriba y/o hacia abajo los ficheros *.asm.

    En el volumen 2 ya no cometí ese error, e incluí en los ficheros *.ZIP los ficheros *.asm y el fichero *.cbmprj.

    Por favor, prueba a modificar el orden de los ficheros como te indico. Te debería funcionar.

    Un saludo, HVSW.

    Me gusta

Deja un comentario