Jump to content

Photo

Need some help with labels and branching


2 replies to this topic

#1 Pantomchap OFFLINE  

Pantomchap

    Space Invader

  • 16 posts

Posted Fri May 19, 2017 5:49 PM

How exactly do labels work? I've had a hard time learning their ways and I just can't seem to find out how to use them properly. I also would like to know how to use a branching operation without getting an error telling me that the location is too far away. Lastly, I would like to know if there is a way to make sure that code in a label is not executed when I don't want it to be.

 

I hope this isn't too demanding. I've been living off of modifying the kernel that is used in the tutorial here and so far I haven't gone as far as making major changes like branching and new labels. 

 

Thanks for reading.



#2 alex_79 OFFLINE  

alex_79

    Stargunner

  • 1,017 posts
  • Location:Italy

Posted Sat May 20, 2017 7:49 AM

Labels are not 6502 instructions, they are only used as aliases for addresses.
 
When you put a label in your source before a piece of code (or data), dasm will assign the address of the next byte as the value of the label. When you compile, every time dasm encounter that label as an instruction operand, it will replace it with the address value.

Branch instructions are a special case, as their operand in 6502 machine language is not an absolute address, but an offset from the address of the next instruction. This offset is a 1 byte signed value, therefore branches can only span from -128 to +127 bytes relative to the next instruction address.

Despite this, when coding in assembly, you specify an address as the operand of the branch instruction (either by using the actual value or a label), and the assembler will calculate the corresponding offset to be used in the resulting machine code at compile time. If the calculated offset is out of the above range, you'll get an error and dasm will abort compiling.

You have to reorganize your code so that every brach occurs in the valid range.

A simple workaround is to invert the branch condition and make it skip a "jmp" instruction, as this use a full address as operand and can jump anywhere in memory.

E.g. if you need to brach to "Dest_Code" when a previous instruction results in a zero, but "Dest_Code" address is out of range, you can replace this

    ...
    beq Dest_Code
    ...

with this:
 

    ...
    bne skip_jmp
    jmp Dest_Code
skip_jmp
    ...

Lastly, I would like to know if there is a way to make sure that code in a label is not executed when I don't want it to be.

Since labels are just aliases defined in the assembly and do not generate 6502 machine code by themselves, there is not code "inside" a label. And the presence of a label doesn't change the flow of the program. You must use jump and branch instructions to do that.



#3 Pantomchap OFFLINE  

Pantomchap

    Space Invader

  • Topic Starter
  • 16 posts

Posted Sat May 20, 2017 10:13 AM

Labels are not 6502 instructions, they are only used as aliases for addresses.
 
When you put a label in your source before a piece of code (or data), dasm will assign the address of the next byte as the value of the label. When you compile, every time dasm encounter that label as an instruction operand, it will replace it with the address value.

Branch instructions are a special case, as their operand in 6502 machine language is not an absolute address, but an offset from the address of the next instruction. This offset is a 1 byte signed value, therefore branches can only span from -128 to +127 bytes relative to the next instruction address.

Despite this, when coding in assembly, you specify an address as the operand of the branch instruction (either by using the actual value or a label), and the assembler will calculate the corresponding offset to be used in the resulting machine code at compile time. If the calculated offset is out of the above range, you'll get an error and dasm will abort compiling.

You have to reorganize your code so that every brach occurs in the valid range.

A simple workaround is to invert the branch condition and make it skip a "jmp" instruction, as this use a full address as operand and can jump anywhere in memory.

E.g. if you need to brach to "Dest_Code" when a previous instruction results in a zero, but "Dest_Code" address is out of range, you can replace this

    ...
    beq Dest_Code
    ...

with this:
 

    ...
    bne skip_jmp
    jmp Dest_Code
skip_jmp
    ...

 

 

Oh I get it now. Thank you so much. You've been a great help.






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users