185. JSR 绝对寻址
接入 JSR 绝对寻址操作码 $20。
第 185 / 356 · tests/chapter_01_cpu/test_185_JSR_absolute.py
前置条件:第 184 步已添加 `jsr。在本步骤中,向 emulator/cpu/opcodes.py` 添加以下改动:
from emulator.cpu.instructions import jsr
from emulator.cpu.addressing_modes import absolute
def jsr_absolute(cpu: CPU):
addr = absolute(cpu)
jsr(cpu, addr)
OPCODE_TABLE = {
# existing entries...
0x20: jsr_absolute,
}操作码
0x20 -> JSR $hhhh目标
创建 jsr_absolute(cpu),使用 absolute(cpu),然后调用 jsr(cpu, addr)。
学习指引
JSR 绝对寻址使用一个 16 位小端序操作数作为子程序地址。
示例
20 34 12 -> JSR $1234执行步骤
1. CPU.step() fetches opcode 0x20.
2. absolute(cpu) fetches operand bytes 34 12 and returns $1234.
3. PC now points to the next instruction, $8003 in these tests.
4. jsr(cpu, $1234) pushes return address $8002.
5. PC becomes $1234.常见错误
不要调用 jmp(cpu, addr)。JSR 必须先压入返回地址。
本步骤存在的原因
`absolute 消费两字节的目标地址,使 PC 停留在下一条指令处,从而让 jsr` 能够压入 PC 减一后的值并跳转。不变量:该步骤消费操作码加操作数,先压入高字节再压入低字节,S 递减两次,PC 变为目标地址,并保持状态不变。常见误解:与 JMP 共用同一种寻址方式,并不意味着 JSR 只是一次普通跳转。
本步骤范围之外:`rts` 与操作码 $60 属于第 186-187 步。BRK、RTI 以及后续通用的栈辅助函数不属于本次改动。
运行本课
uv run pytest tests/chapter_01_cpu/test_185_JSR_absolute.py -v