186. rts 指令

添加与寻址方式无关的 RTS 行为。

186 / 356 · tests/chapter_01_cpu/test_186_instruction_rts.py

前置条件:第 184-185 步已添加 JSR 行为及操作码接入。在本步骤中,添加 `emulator/cpu/instructions.py::rts`:

指令

RTS -> Return from Subroutine

目标

在 instructions.py 中实现 rts(cpu)。

学习指引

RTS 是与 JSR 相匹配的返回指令。JSR 把返回地址保存到栈上,RTS 则把该地址取回,再加 1 以便从原 JSR 指令之后继续执行。

重要细节

  • 栈位于 $0100 页。
  • S 只是栈地址的低字节。
  • 出栈时先递增 S,再从 $0100 | S 读取。
  • RTS 先取出低字节,再取出高字节。
  • RTS 将 PC 设为取出的地址加 1。

示例

If the stack contains return address $8002:

    $01FC = $02  low byte
    $01FD = $80  high byte
    S = $FB

Then RTS pulls $8002 and sets PC to $8003.

示例实现结构

cpu.s = (cpu.s + 1) & 0xFF
low = cpu.bus.read(0x0100 | cpu.s)

cpu.s = (cpu.s + 1) & 0xFF
high = cpu.bus.read(0x0100 | cpu.s)

addr = (high << 8) | low
cpu.pc = (addr + 1) & 0xFFFF

本步骤存在的原因

JSR 存入的是 PC 减一后的值,因此 RTS 需要重新组合出这个字并前进一步以到达继续执行的位置。不变量:每次出栈都先递增 8 位的 S 再读取;先取低字节后取高字节;最终的 PC 会回绕到 16 位;状态、其他寄存器和内存保持不变。常见误解:先读取再递增 S,或省略最后对 PC 的加一,都不能反转 JSR 的栈协议。

本步骤范围之外:导入并映射操作码 $60 是第 187 步的内容。BRK/RTI 以及共用的 CPU 栈辅助函数属于后续步骤。

运行本课

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