十、观察点追踪
现在我们来想办法找出游戏的程序是如何来指定在这里写入相应的字符的。这里要用到BGB调试模式中“观察点”功能。在bgb debugger窗口下,点击菜单栏的Debug,选择Watchpoints

会打开如下的窗口

下方的几个输入框,addr range表示要观察的地址,value表示要观察的数值,on read表示读取,on write表示写入,on execute表示执行,on jump表示跳转。
这里我们在程序显示“い”时设置观察点,看看可不可以做一些文章。前面我们已经看到了,9987这里要放7B这个Tile,就是在地址9987,写入数值7B,设置好之后添加并启用。表示当程序往9987这个地址写入7B这个数值时,就会暂停。同样把另外三个Tile写入的观察点也添加进去。

然后我们在游戏中再次来到刚才的画面,会看到游戏停住了,并且bgb debugger窗口跳了出来,同时有一行程序被蓝色高亮标记

这里对应的程序是
ld (hl),a
这一句的意思是把寄存器a上的值写到寄存器hl对应的地址上。
我们看右上角的小窗,第一行af=7B40,7B40是双字节,所以a就是7B,对应要写入的Tile编号;第四行hl=9987,对应的就是要写入的地址。这一语句的意思就是把编号为7B的Tile写到地址9987上。正好是我们想找的。
之前“え”这个字对应的4个Tile的编号是7D,7E,9D,9E,我们试试让这里显示“え”这个字符。右键点击af=7B40选择edit register(编辑寄存器),输入7D,点击OK确认。BGB模拟器可以修改游戏运行中的参数,并实时的看到修改的效果。鼠标点击游戏界面,游戏在下一个观察点停止,此时的操作是要把7C写到9988,我们再把7C改为7E,这样我们依次把四个观察点的a值都改为“え”这个字对应的Tile编号。此时游戏显示的画面如下

确实如我们所想的,“い”被改成了“え”。但是当我们在游戏中重新进入这一界面后,又变回了原来的显示。这是因为之前寄存器中a的值是通过其他方式计算出来,暂存在这里的,每次进入这一界面,游戏都会重新计算一次,所以只有找到最原始保存在Rom中的数值去做修改,才能彻底修改成功。
所以我们就要去看7B这个数值是怎么来的。再次来到第一个观察点游戏暂停的位置,在bgb debugger中,我们同时按shift+F7,可以看到蓝色高亮标记往上移动了一行。F7是trace的快捷操作,表示程序正向运行一步,shift+F7就是trace reverse,程序往回倒退一步。我们就不断回溯去找7B这个值的由来。

到这一步时我们看到a的值变成了00,所以这一步程序让a的值变成了7B。这一句程序是
pop af
pop是从栈中取回值的操作,pop af就是从栈中取回值到寄存器af。与之对应的是push命令,它的作用是把寄存器中的值推到栈里暂存。我们看到右下窗口中被高亮的正是
WRA0:CFE1 7B40
表示此时栈里的数值是7B40。在下一步,它就会被取回到af中。
所以这里还不是7B的原始出处,我们还要继续往上追踪,同时注意观察右上角的寄存器和下方的WRAM中7B这个数值出现和消失的变化。
当刚好追踪到下面这一句时,7B在寄存器和WRAM中都没有出现

这里对应的程序是
ld a,(de)
这一句的意思是把寄存器de对应的地址上的值写到寄存器a上。
按F7,运行一步,a的值就变成了7B,因此de对应的地址6FEC这里可能就是7B这个值最开始的由来。