011. Lda 绝对寻址
添加绝对寻址的 LDA($AD)。
第 11 / 356 · tests/chapter_01_cpu/test_011_LDA_absolute.py
要更新的文件
emulator/cpu/cpu.py位置
CPU.step, new $AD branch为什么需要这一步
立即寻址的 LDA 直接加载其操作数。绝对寻址的 LDA 则消耗一个两字节的小端序地址,读取存储在该地址处的值,并应用与测试 010 中所学相同的零标志位与负标志位行为。
完整示例实现
ZERO_FLAG = 1 << 1
NEGATIVE_FLAG = 1 << 7
class CPU:
def step(self) -> None:
opcode = self.fetch_byte()
if opcode == 0xA9:
self.a = self.fetch_byte()
if self.a == 0:
self.p |= ZERO_FLAG
else:
self.p &= ~ZERO_FLAG
if self.a & NEGATIVE_FLAG:
self.p |= NEGATIVE_FLAG
else:
self.p &= ~NEGATIVE_FLAG
return
if opcode == 0xAD:
address = self.fetch_word()
self.a = self.bus.read(address)
# In this step, flag behavior is intentionally
# duplicated before Test 012 extracts the common helper.
if self.a == 0:
self.p |= ZERO_FLAG
else:
self.p &= ~ZERO_FLAG
if self.a & NEGATIVE_FLAG:
self.p |= NEGATIVE_FLAG
else:
self.p &= ~NEGATIVE_FLAG
return
raise NotImplementedError(
f"Opcode {opcode:02X} not implemented"
)重要不变量
- $AD 消耗三个指令字节:操作码、低位地址、高位地址
- 总线读取使用组装完成的 16 位地址
- Z/N 的置位与清零在连续指令之间都能正常工作
常见误解
字节 34 12 并不是加载到 A 中的值 $1234。它们组成的是地址 $1234;LDA 随后加载存储在该地址处的字节。
范围之外
- 将共享的标志位逻辑提取到辅助函数中
- 提取寻址函数与指令函数
- 其他 LDA 寻址模式
运行本课
uv run pytest tests/chapter_01_cpu/test_011_LDA_absolute.py -v