1Learning Outcomes¶
Contrast PC-Relative Addressing with Absolute Addressing.
Given assembly code with labels, compute PC-relative offsets for conditional branches and unconditional jumps.
We recommend reviewing RISC-V control flow before continuing.
One section describes how by default, the Program Counter (PC) is incremented by 4 bytes, corresponding to the next sequential instruction.
Another section describes unconditional jumps (e.g.,
j Label) and conditional branches (e.g.,beq rs1 rs2 Label).
2Addressing Modes¶
There are different addressing modes–that is, ways of using operands and/or addresses encoded in the instruction.
We have seen one addressing mode already with loads and stores. These instructions use base or displacement addressing, which computes addresses as a sum of a register in the register file (x0-31) and a immediate constant encoded in the instruction.
RISC-V uses two addressing modes to compute instruction addresses to update the PC:
PC-relative addressing, which computes addresses by summing PC with a signed constant offset, e.g.,
PC = PC + offsetAbsolute addressing, which computes addresses from a register, e.g.,
PC = R[rs1] + imm.
2.1PC-Relative Addressing¶
In almost all cases, instructions update the PC using PC-relative addressing.
Arithmetic instructions, loads, and stores:
offsetis +4Branches
J-Type instructions (see a later section)
(Effectively, all instructions except
jalr)
Why? Position-Independent Code. If all an entire code block, these relative offsets won’t change!
2.1.1From Labels to PC-Relative Offsets¶
Recall that in assembly, unconditional jumps and conditional branches uses labels, e.g., j Label and beq rs1 rs2 Label. Labels are not instructions and do not actually “exist” in machine code.
Building machine instructions therefore requires translating labels into numeric constants that can be used for addressing. All branch and jump instructions that use labels use PC-relative addressing.
To translate branch and jump instructions to machine code, we must compute PC-relative offsets, which are numeric constants.
1. beq x19 x10 End, if branch is not taken. In this case, PC updates to the next sequential instruction. The PC-relative offset is +4.
2. beq x19 x10 End, if branch is taken. In this case, PC updates to the instruction tagged with the End label. Consider Figure 1, which assigns toy addresses to each instruction in the above assembly. Here, the pc updates from beq (at address 0x0C) to End’s instruction (at address 0x1C). This difference is 0x10, or +16. This corresponds to the fourth instruction after beq.

Figure 1:Code illustrated example with jump operation.
j Loop. In this case, PC updates to the instruction tagged with theLooplabel (here,beq). Still considering Figure 1, thepcupdates fromj(at address0x18) toLoop’s instruction (at address0x0C). This difference is -12. This corresponds to three instructions beforej.
2.2Absolute Addressing¶
By contrast, absolute addressing supplies a new address to overwrite the PC. This addressing mode is position-dependent and is brittle to code movement (as we will see later).
Only jalr (an I-Type instruction) uses absolute addressing by setting PC = R[rs1] + imm. Doing so often involves building a 32-bit immediate, which is possible using the U-Type instruction format we discuss in this chapter.