TI-84 Plus CE Z80汇编中(HL)与(BC/DE)内存访问差异问询
你遇到的异常完全是由TI-84 Plus CE搭载的eZ80 CPU在ADL模式下的24位寄存器特性导致的,核心问题是你只复制了HL寄存器的低16位到DE,丢失了高8位的地址部分,导致两个寄存器对指向完全不同的内存区域。
具体分析
ADL模式下的寄存器结构
当你用.assume ADL=1开启24位地址模式后,HL是一个完整的24位寄存器,由三个8位分量组成:H':高8位地址H:中8位地址L:低8位地址
而saveSScreen的实际地址是0xD00000,所以初始加载后,HL的三个分量分别是H'=0xD0、H=0x00、L=0x00。
加法操作后的地址变化
你执行ADD HL, DE时,DE是16位寄存器(值为0x0002),会被符号扩展为24位的0x000002,加到HL后得到HL=0xD00002(H'=0xD0、H=0x00、L=0x02)。错误的寄存器复制
你用ld D, H和ld E, L复制地址时,只取了HL的中8位和低8位,也就是D=0x00、E=0x02,DE作为16位寄存器的值是0x0002。在ADL模式下访问内存时,16位寄存器会被符号扩展为24位,所以DE指向的地址是0x000002,而HL指向的是0xD00002——这两个是完全无关的内存区域,读出来的值自然不同。直接赋值的正确原因
当你直接写ld HL, s_mem_start + 2和ld DE, s_mem_start + 2时,spasm-ng编译器会自动生成24位加载指令,把完整的24位地址0xD00002加载到HL和DE的24位寄存器版本中,所以两个寄存器对指向同一个地址,输出自然一致。
解决方案
要完整复制HL的24位地址到DE,不需要手动拆分寄存器,直接使用eZ80的24位寄存器传输指令即可:
ld HL, s_mem_start ld DE, 2 ADD HL, DE LD DE, HL ; 完整复制24位地址 ld A, (HL) call _PutC ld A, (DE) call _PutC
替换后运行,就能得到和直接赋值相同的vv输出。
内容的提问来源于stack exchange,提问作者user197974

