183. JMP 间接寻址
接入 JMP 间接寻址操作码 $6C。
第 183 / 356 · tests/chapter_01_cpu/test_183_JMP_indirect.py
前置条件:第 180 步已添加 `indirect,第 181 步已添加 jmp。在本步骤中,向 emulator/cpu/opcodes.py` 添加以下改动:
from emulator.cpu.instructions import jmp
from emulator.cpu.addressing_modes import indirect
def jmp_indirect(cpu: CPU):
addr = indirect(cpu)
jmp(cpu, addr)
OPCODE_TABLE = {
# existing entries...
0x6C: jmp_indirect,
}操作码
0x6C -> JMP ($hhhh)目标
创建 jmp_indirect(cpu),使用 indirect(cpu),然后调用 jmp(cpu, addr)。
学习指引
JMP 间接寻址把操作数当作指向目标地址的指针来使用。
示例
6C 00 02 means JMP ($0200)如果
memory[$0200] = $34
memory[$0201] = $12那么
PC = $1234重要提示
indirect(cpu) 已经返回了最终的目标地址。该操作码的处理函数不能再对这个返回的地址进行内存读取。
NES/6502 的 bug
如果指针以 $FF 结尾,高字节会在同一页内发生回绕:
JMP ($02FF) reads high byte from $0200, not $0300.本步骤存在的原因
`addressing_modes.indirect 消费指针操作数,按照 6502 的页边界行为进行处理,并返回最终目标地址;随后由 jmp 将其赋值。不变量:该处理函数不会执行额外的目标地址读取,保持标志位/寄存器/栈/内存不变,并且只映射 $6C。常见误解:indirect` 返回的值并不是另一个指针。
本步骤范围之外:实现或修改 `addressing_modes.indirect` 属于第 180 步。JSR 从第 184 步开始;RTS 与中断属于后续步骤。
运行本课
uv run pytest tests/chapter_01_cpu/test_183_JMP_indirect.py -v