I'm currently teaching myself assembly language by building an assembler for the Arduino Uno. However, I am struggling with converting RJMP to binary.
From the amtel documents, RJMP is represented in binary as 1100 kkkk kkkk kkkk
where k
is the relative address to jump to.
Assembling the following code:
check_press_loop:
sbis PIND, 2
rjmp check_press_loop
And disassembling I get:
10: fe cf rjmp .-4 ; 0xe
I understand why the relative jump is -4 bytes, what I don't understand is how this is represented by the hex fc ef
. Swapping the order due to the "little endian" byte order (cf fe
) gives a binary value of 0b1100111111111110
. Removing the instruction (1100
) part of the binary value, how does 111111111110
represent -4?
Hopefully you know that 111111111110
is -2 when interpreted as a twos-complement signed integer. The reason why -2 is used here is because check_press_loop
is two 16-bit words back from the end the RJMP instruction. Since AVR instructions are always word aligned there's no reason for RJMP instruction to be able to encode a jump offset measured in bytes. The processor isn't capable of executing an instruction at an odd byte address in program memory, the PC register isn't capable of holding such an address.