Here's an example showing the correspondence between assembly (what you call "shorthand") and machine code. First, here's the assembly code for the algorithm, with some parameters abstracted away:
* = 4000 ; This is the address where our program will be stored
LDX #len
loop LDA src,X
STA dest,X
DEX
BNE loop
Of course, you can't turn that directly into machine code. You also need to fill in the values of len
, src
and dest
:
src = $1234
dest = $5678
len = 10
The thing to understand about the loop
name is that just like src
is assigned the value $1234
, loop
will be assigned the address of the instruction after it. So in this case, since LDX #len
takes up 2 bytes (as I'll show you shortly), loop
is set to $4000 + 2 = $4002
. This is done automatically by the assembler, but of course you could do all this on paper as well.
So what is the 6502 machine code for the above assembly program?
A2 0A
BD 34 12
9D 78 56
CA
D0 F7
How do I know this? Well, I've just pasted the above program into the online 6502 assembler at http://www.masswerk.at/6502/assembler.html. It even shows you the detailed mapping between assembly and machine code:
4000 LDX #LEN A2 0A
4002 LOOP LDA SRC,X BD 34 12
4005 STA DEST,X 9D 78 56
4008 DEX CA
4009 BNE LOOP D0 F7
400B
Note how the actual value of LOOP
is not even used to compute the machine code for BNE LOOP
, only its relative address compared to the BNE
instruction itself: F7
is -9, and the difference between $400B
and $4002
is -9!
So if you were to do this by hand, you'd just translate everything else into machine code, then when you get to a jump, you compute the difference between the next instruction's starting address and the jump destination's address. It should be negative for backwards jumps and positive for forward jumps.