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?
A jump instruction, like "jmp", just switches the CPU to executing a different piece of code. It's the assembly equivalent of "goto", but unlike goto, jumps are notconsidered shameful in assembly.
A jump is unconditional and the bits saved by leaving out the condition can be used for the address. A jump allows for a 26 bit address and so can jump much further in the code than a branch. At the expense of not being conditional. Note this might be true for MIPS, but not for all CPU mnemonics.
The machine cycle automatically executes instructions in sequence. When a jump instruction executes (in the last step of the machine cycle), it puts a new address into the PC. Now the fetch at the top of the next machine cycle fetches the instruction at that new address.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With