4

In the Jump instruction,

  1. why do we shift 26-bit address to 28-bit?
  2. why do we add the leftmost 4-bit from PC to the 28-bit?
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Elmasry
  • 112
  • 1
  • 10
  • 1
    1. because MIPS instructions have to be aligned, so we get a longer jump displacement instead of wasting the low 2 bits. [In MIPS, why can a jump instruction set the program counter to a 28-bit target address](https://stackoverflow.com/q/42219553) / [MIPS jump and branch instructions range](https://stackoverflow.com/q/36442586) 2. because they decided to design it that way, instead of as a relative branch. – Peter Cordes Apr 06 '20 at 17:53
  • @PeterCordes can u explain more about the relative branch – Elmasry Apr 06 '20 at 18:34
  • [How to Calculate Jump Target Address and Branch Target Address?](https://stackoverflow.com/q/6950230) shows how MIPS `b` instructions like `beq` work. – Peter Cordes Apr 06 '20 at 19:06

1 Answers1

5

Why do we shift 26-bit address to 28-bit?

When we shift the address by 2 bits, the argument (address) of the jump instruction can be in the range 0...2^28-1.

If we didn't shift the address, it could only be in the range 0...2^26-1.

This means we could only use 1/4 of the address space.

On the other hand, the apperent benefit of not shifting the address would not really be a benefit:

Not shifting the address would allow using addresses which are not divisible by 4. However, because instructions are always located at addresses which are divisible by 4, a jump instruction to an address not divisible by 4 makes no sense.

By the way: Other CPUs (e.g. MC68000) indeed use 16-bit "branch" (jump) instructions where the low bit always has to be zero - and therefore more memory could be addressed if the CPU shifted the address by one.

why do we add the leftmost 4-bit from PC to the 28-bit?

The PC register is 32 bits wide and the jump instruction contains only 26 bits. So we have to take 6 bits from somewhere else:

The low 2 bits of the PC register are always zero, so we still have to think about the "left" 4 bits.

If we would always set the left 4 bits to zero, we could only jump to some code located inside the first 256 Megabytes of memory.

If we simply don't modify the the left 4 bits of the PC, we can jump to some code which is located in the same 256 Megabytes range as the jump instruction itself.

Let's think about a for() or while() loop:

At the end of such a loop there is a jump instruction to the start of the loop.

Let's assume that the program is not neccessarily located in the first 256 Megabytes of memory.

What is more likely:

That the start of the loop is in the same 256-Megabytes-range as the end of the loop (the jump instruction) or that the start of the loop is inside the first 256 Megabytes of memory?

Martin Rosenau
  • 17,897
  • 3
  • 19
  • 38
  • *At the end of such a loop there is a jump instruction to the start of the loop.* Normally you'd use a conditional branch as the loop branch, like `bne` something. MIPS conditional branches are relative, adding an offset to PC. Or if you transliterate a C loop to asm with an unconditional branch at the bottom, you can still do short-range unconditional relative branches by using an always-true condition like `bgez $zero, loop_top`. But sure, as an example it works, and lots of hand-written MIPS code does use `j` for such branches. – Peter Cordes Apr 07 '20 at 13:37
  • thanks, the second question bother me for a long time – Jesse Aug 11 '20 at 09:25
  • the example about `for` and `while` is strange, the jump instruction is at the end, how can it jump backward to the start of loop? It must be relative jump. – shino Jan 08 '22 at 07:41
  • @shino Indeed, there will typically be relative jumps at the end of a loop. One of the reasons is that no relocation is required. However, it is also possible to use a `J` instruction. If the loop is longer than 32K instructions, you even have to use `J` instead of `BGEZ` because the start of the loop is too far away for `BGEZ`. – Martin Rosenau Jan 08 '22 at 08:38