To assemble jumps and branches there are some new tricks that we have to take into account. One is the times-4 trick; it applies to both types of instruction. The subtract-where-you-came-from trick applies only to the branch instructions.
We will use the following symbol table in the examples:
| here | 0x00400040 |
| there | 0x00400084 |
| elsewhere |
0x004000CC |
| backthere | 0x00400024 |
Jump instructions use direct mode, so we simply look up the target in the symbol table, apply the times-4 trick, and put the result into the target field of the instruction. Here is an example
j there
j 0x00400084
| 2 |
0x00400084 |
| 2 |
0x00100021 |
| 000010 |
00 0001 0000 0000 0000 0010 0001 |
08100021
We look up the value of "there" in the symbol table, find 0x00400084, and rewrite the instruction using this value instead of the label. Then we fill in the top row of the table by translating the j into its opcode from the back cover of the book and copying the target address into the target field. We fill in the middle row by copying the opcode down and filling the target field with one fourth of the target field in the row above. Remember, this division will always have a remainder of zero. The bottom row is just the middle row expressed in binary, a 6-bit field and a 26-bit field. Finally, we turn this into hex, and we have the answer as we would see it in SPIM. If you write a long enough program, you can feed it into SPIM and check that this is correct.
Of course, when this is done by the computer, all of the arithmetic is in binary, so the divide by four is just a shift two places to the right.
In this case we have to look up the target address, subtract the address of the branch instruction (which we will call the current address) from it, and apply the times-4 trick to the difference. That value will get trimmed to 16 bits and be placed into the target field of the branch. Here is an example in which the subtraction is 0x00400084 - 0x00400040 = 0x44.
here: beq $10, $12, there
beq $10, $12, 0x00400084
| 4 | 10 | 12 |
0x00400084 - 0x00400040 |
| 4 | 10 | 12 |
0x44 |
| 4 | 10 | 12 |
0x11 |
| 000100 | 01010 | 01100 |
0000 0000 0001 0001 |
114C0011
Again, you can check this using SPIM, but be sure to put the beq instruction at the right place (0x00400040).Be sure that you distinguish carefully between decimal and hexadecimal numerals. It is very easy to get that wrong. I made that very mistake while making the first version of this page.