163. 相对寻址

解码一个八位的相对分支偏移量。

163 / 356 · tests/chapter_01_cpu/test_163_relative_addressing.py

为什么需要这一步

分支指令存储的是相对于其操作数之后 PC 的一个带符号位移,而不是完整的目标地址,因此解码过程必须与分支决策分离。

在这一步中,只需在 `emulator/cpu/addressing_modes.py::relative` 中添加以下实现:

def relative(cpu: CPU) -> int:
    offset = cpu.fetch_byte()
    # Transform to signed integer
    # 0x7F -> +127
    # 0x80 -> -128
    # 0xFF -> -1
    if offset & 0x80: # offset has bit 7 active, is negative
        offset -= 0x100
    return offset

`CPU.fetch_byte 读取操作数并使 PC 前进一次;对第 7 位被置位的值减去 0x100,可以将无符号的 0x80..0xFF 映射为带符号的 -128..-1,同时将 0x00..0x7F 保持为 0..127`。

不变量:这个辅助函数总是恰好消耗一个字节,并且从不会把 PC 改成返回的偏移量本身。它不检查标志位,也不修改寄存器、内存或状态。常见误解:`relative` 只负责解码位移;它既不决定是否发生分支,也不自行计算绝对目标地址。

超出范围:`instructions.bcc` 属于第 164 课。其他分支语义属于第 165-171 课,操作码处理函数/表项属于第 172-179 课。

运行本课

uv run pytest tests/chapter_01_cpu/test_163_relative_addressing.py -v