MIPS - JAL confusion: $ra = PC+4 or PC+8?

ReimannCL picture ReimannCL · Mar 3, 2012 · Viewed 17.1k times · Source

I'm having trouble understanding how the instruction jal works in the MIPS processor. My two questions are:
a) What is the value stored in R31 after "jal": PC+4 or PC+8?
b) If it's really PC+8, what happens to the instruction at PC+4? Is it executed before the jump or is it never executed?

In Patterson and Hennessy (fourth edition), pg 113:

"jump-and-link instruction: An instruction that jumps to and address and simultaneously saves the address of the following instruction in a register ($ra in MIPS)"

"program counter (PC): The register containing the address of the instruction in the program being executed"

After reading those two statements, it follows that the value saved in $ra should be (PC+4).

However, in the MIPS reference data (green card) that comes with the book, the jal instruction's algorithm is defined like this:
"Jump and Link : jal : J : R[31]=PC+8;PC=JumpAddr"

This website also states that "it's really PC+8", but strangely, after that it says that since pipelining is an advanced topic "we'll assume the return address is PC+4".
I come from 8086 assembly, so I'm aware that there's a big difference between returning to an address and to the one following it, because programs won't work if I just assume something that's not true. Thanks.

Answer

Richard Pennington picture Richard Pennington · Mar 3, 2012

The address in $ra is really PC+8. The instruction immediately following the jal instruction is in the "branch delay slot". It is executed before the function is entered, so it shouldn't be re-executed when the function returns.

Other branching instructions on the Mips also have branch delay slots.

The delay slot is used to do something useful in the time it takes to execute the jal instruction.