版本默认为991cnxVerC.一楼我先讲使用08EA4实现的多次分支方法,故命名为08EA4分支法。(我也称其为EA分支法,因为此方法操作过程与EA相关)
EA分支法依赖双字节遍历函数08EA4(如果看不懂的话可以去看楼下的一个实例,这里介绍利用其判断键码的分支方法,此函数的其他用法我放在楼下):
![](http://tiebapic.baidu.com/forum/w%3D580/sign=c928986f7f12b31bc76ccd21b6193674/a605ad773912b31b0af4c901c018367adbb4e183.jpg?tbpicau=2025-02-20-05_a03e036d18ecc1e9f927a3320cefcb9d)
其遍历EA处内容并判断其是否与ER0相等,如果是就将ER0设为0后POP PC返回,如果读到0000就直接POP PC返回,故与ER0相等的地址存储在EA里,由于执行了EA+指令,所以EA存储的地址=实际与ER0相等的地址+2
我们首先写两个表,从前到后分别为要判断的键码表和对应的跳转地址表,注意键码表的最后两个字节需设为0000以中断遍历,跳转地址表的最后两个字节为此次按下的按键不在键码表内时的跳转地址。表存在内存的任意位置(最好存在程序后面避免PUSH指令污染),但是使用时需要将其复制到其他位置,再在这个位置用08EA4进行遍历,因为后面[EA+]的ST指令会破坏这个表
接下来,我们在ER0内放入键码,用08EA4遍历键码表,随后给EA加上一个特定的数值,使EA由键码表中的地址指向跳转地址表中的对应地址,读取EA处的地址进行跳转,我们就完成了分支。
调用08EA4遍历前需要两步:赋值EA为表头位置,然后在ER0内放入键码。注意由于17B40会破坏ER0所以步骤不可颠倒
我们使用17B40赋值EA:
![](http://tiebapic.baidu.com/forum/w%3D580/sign=5172f8f253ce36d3a20483380af23a24/8e3dcdea15ce36d3dffe87187cf33a87e850b1ac.jpg?tbpicau=2025-02-20-05_76f6ac899c8ede6ca050585405f7ba06)
在ER12=ER14的情况下将EA设为ER14+0xA且不会对内存造成破坏,注意此函数为RT结尾,调用前应设置LR
实际上也可直接调用17B46,将EA设为ER12+0xA,但是这样会污染ER12后面的0xA个字节,需谨慎使用
也可使用10E76赋值EA:
![](http://tiebapic.baidu.com/forum/w%3D580/sign=a6de4e262109c93d07f20effaf3cf8bb/1c9f7b3e6709c93d1f060adfd93df8dcd00054ae.jpg?tbpicau=2025-02-20-05_f5aa3a953e8826f5c34634a6db0e6085)
可见在调用10E76前需将R6设为01以避免跳出函数,注意此函数结尾会POP XR4,需预留4个字节空间
如何给EA加上特定的数值呢?ROM中并没有ADD EA,ERn这样一条指令,但是我们仍可使用194D0:
![](http://tiebapic.baidu.com/forum/w%3D580/sign=dadaa1f730c6a7efb926a82ecdfbafe9/329994ef76c6a7eff3d0ac0ebbfaaf51f2de66a8.jpg?tbpicau=2025-02-20-05_21b14e6650f081d291f9bee5856d4d86)
可以看到,其多次使用[EA+]指令,将EA增加了0xA.若从其他地址进入函数,就可以给EA加上特定的数值(数值只能是偶数,若使用1C372则可以使数值为奇数)。尽管ST指令破坏了表,但EA处的内容不会被污染。
我们使用1C368读取EA处内容:
![](http://tiebapic.baidu.com/forum/w%3D580/sign=94f573bf9f33c895a67e9873e1127397/daac46a7d933c8954a929c53971373f0830200b6.jpg?tbpicau=2025-02-20-05_d7cef8cebbc3d075a9ad140f0e7f2f79)
其将EA处内容读取至ER6,并将EA+0x8处的内容读取至ER14,随后可使用对应跳转指令进行跳转完成分支。
从1C36C开始是把读取到的内容写入D000处,我们的程序一般不在D000处所以不会被污染。后面我要讲的1B9B0也具有类似的结构,最终使得EA为定值,可利用此特性判断EA是否被更改(楼下会讲),应用于像素编辑器上判断光标位置是否超出屏幕
EA分支法依赖双字节遍历函数08EA4(如果看不懂的话可以去看楼下的一个实例,这里介绍利用其判断键码的分支方法,此函数的其他用法我放在楼下):
![](http://tiebapic.baidu.com/forum/w%3D580/sign=c928986f7f12b31bc76ccd21b6193674/a605ad773912b31b0af4c901c018367adbb4e183.jpg?tbpicau=2025-02-20-05_a03e036d18ecc1e9f927a3320cefcb9d)
其遍历EA处内容并判断其是否与ER0相等,如果是就将ER0设为0后POP PC返回,如果读到0000就直接POP PC返回,故与ER0相等的地址存储在EA里,由于执行了EA+指令,所以EA存储的地址=实际与ER0相等的地址+2
我们首先写两个表,从前到后分别为要判断的键码表和对应的跳转地址表,注意键码表的最后两个字节需设为0000以中断遍历,跳转地址表的最后两个字节为此次按下的按键不在键码表内时的跳转地址。表存在内存的任意位置(最好存在程序后面避免PUSH指令污染),但是使用时需要将其复制到其他位置,再在这个位置用08EA4进行遍历,因为后面[EA+]的ST指令会破坏这个表
接下来,我们在ER0内放入键码,用08EA4遍历键码表,随后给EA加上一个特定的数值,使EA由键码表中的地址指向跳转地址表中的对应地址,读取EA处的地址进行跳转,我们就完成了分支。
调用08EA4遍历前需要两步:赋值EA为表头位置,然后在ER0内放入键码。注意由于17B40会破坏ER0所以步骤不可颠倒
我们使用17B40赋值EA:
![](http://tiebapic.baidu.com/forum/w%3D580/sign=5172f8f253ce36d3a20483380af23a24/8e3dcdea15ce36d3dffe87187cf33a87e850b1ac.jpg?tbpicau=2025-02-20-05_76f6ac899c8ede6ca050585405f7ba06)
在ER12=ER14的情况下将EA设为ER14+0xA且不会对内存造成破坏,注意此函数为RT结尾,调用前应设置LR
实际上也可直接调用17B46,将EA设为ER12+0xA,但是这样会污染ER12后面的0xA个字节,需谨慎使用
也可使用10E76赋值EA:
![](http://tiebapic.baidu.com/forum/w%3D580/sign=a6de4e262109c93d07f20effaf3cf8bb/1c9f7b3e6709c93d1f060adfd93df8dcd00054ae.jpg?tbpicau=2025-02-20-05_f5aa3a953e8826f5c34634a6db0e6085)
可见在调用10E76前需将R6设为01以避免跳出函数,注意此函数结尾会POP XR4,需预留4个字节空间
如何给EA加上特定的数值呢?ROM中并没有ADD EA,ERn这样一条指令,但是我们仍可使用194D0:
![](http://tiebapic.baidu.com/forum/w%3D580/sign=dadaa1f730c6a7efb926a82ecdfbafe9/329994ef76c6a7eff3d0ac0ebbfaaf51f2de66a8.jpg?tbpicau=2025-02-20-05_21b14e6650f081d291f9bee5856d4d86)
可以看到,其多次使用[EA+]指令,将EA增加了0xA.若从其他地址进入函数,就可以给EA加上特定的数值(数值只能是偶数,若使用1C372则可以使数值为奇数)。尽管ST指令破坏了表,但EA处的内容不会被污染。
我们使用1C368读取EA处内容:
![](http://tiebapic.baidu.com/forum/w%3D580/sign=94f573bf9f33c895a67e9873e1127397/daac46a7d933c8954a929c53971373f0830200b6.jpg?tbpicau=2025-02-20-05_d7cef8cebbc3d075a9ad140f0e7f2f79)
其将EA处内容读取至ER6,并将EA+0x8处的内容读取至ER14,随后可使用对应跳转指令进行跳转完成分支。
从1C36C开始是把读取到的内容写入D000处,我们的程序一般不在D000处所以不会被污染。后面我要讲的1B9B0也具有类似的结构,最终使得EA为定值,可利用此特性判断EA是否被更改(楼下会讲),应用于像素编辑器上判断光标位置是否超出屏幕