Here is some MIPS assembly code I wrote to test the jump instruction:
addi $a0, $0, 1
j next
next:
j skip1
add $a0, $a0, $a0
skip1:
j skip2:
add $a0, $a0, $a0
add $a0, $a0, $a0
skip2:
j skip3
loop:
add $a0, $a0, $a0
add $a0, $a0, $a0
add $a0, $a0, $a0
skip3:
j loop
When I run the assembler, here's the result:
[0x000000] 0x20040001 # addi $a0, $zero, 1 ($a0 = 1)
[0x000004] 0x08000002 # j 0x0002 (jump to addr 0x0008)
[0x000008] 0x08000004 # j 0x0004 (jump to addr 0x0010)
[0x00000C] 0x00842020 # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x000010] 0x08000007 # j 0x0007 (jump to addr 0x001C)
[0x000014] 0x00842020 # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x000018] 0x00842020 # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x00001C] 0x0800000B # j 0x000B (jump to addr 0x002C)
[0x000020] 0x00842020 # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x000024] 0x00842020 # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x000028] 0x00842020 # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x00002C] 0x08000008 # j 0x0008 (jump to addr 0x0020)
Looking at the machine code for the jump instructions, this is what I see:
1st jump (just jumps to next instruction) 0x08000002
2nd jump (skips 1 instruction) 0x08000004
3rd jump (skips 2 instructions) 0x08000007
4th jump (skips 3 instructions) 0x0800000B
5th jump (skips 3 instructions backwards) 0x08000008
From looking at these instructions, it looks like the machine code starts with a 08 for the jump instruction, and the number at the end tells the jump instruction where to go. However, I can not figure out how this number is calculated. Also, there is nothing to indicate to me that the 5th jump is a backwards jump.
How is the jump value calculated?
Just look into a reference manual for more details about the opcode encoding.
Short version: In a 32 bit instruction you can not include a 32-bit jump destination. The opcode uses 6 bits, which leaves 26 bits for the instruction. The target address is constructed by taking the first 4 bits of the address of the instruction following the j
instruction, then 2 zero bits are appended to the 26 bits from the jump instruction operand. (As the instructions are 32 bits, alignment is useful and allows the omitting of the last two 0's.)
To the backward jump: The addresses are absolute, NOT relative, so it only depends on the address of the jump instruction, whether it is a forward or a backward jump.
EDIT: More detailed description: We have at address x jump instruction j. Let t represent the jump operand of j. t is 26 bit wide. The bit pattern of address of the next instruction is computed as follows:
upper_6_bits_of(x+4),t,0,0
So the jump is ALWAYS absolute. There are no relative jumps. when the result is smaller than x then it is a backward jump, when it is greater it is a forward jump (and if you want something stupid, you make it equal ;-).
So let's look at the 5th jump of your example:
The first 6 bits of the jump target are: 000000, because the upper 6 bits of the address of the instruction behind the jump are 000000.
The next 26 bits are the lowest 26 bits of the jump instruction, that is 00000000000000000000001000
The last 2 bits are: 00, because the got always appended.
Together we have: 0000000000000000000000000000100000, which is hex 20. And at that address is exactly the label/instruction where the flow should continue.