rt,这是我第一次尝试解析一个地址,也算是一个系统整理,希望能为大家带来帮助
先来看@熠辉_子羿 在全过程解析像素编辑器中所提到的187CC的用法:memcpy(er4,er2) er0 long,从参数我们可以得知,该函数读取ER0的值作为复制长度,ER2的值作为源地址,ER4的值作为目标地址,并进行复制(小端序很重要)接下来,我将通过ROM片段对此地址进行详尽的解析来看ROM:187CC:PUSH ER0//这里困扰了我好久,需要结合后面才能看懂,各位读者目前只需要知道这条指令将ER0的值存入了内存,并覆盖了“CC 87”后面的两字节
MOV ER0,ER4//在ER0中备份目标地址
BL 02h:02DC4h//调用22DC4
POP ER0
POP ER4
POP PC
22DC4:
PUSH ER14
MOV ER14,SP//这里又困扰了我好久,这条地址的作用是在ER14中备份了SP指针指向的地址,由于上一条PUSH指令,此时SP=ER0所在地址-2
PUSH ER12
PUSH ER8
PUSH ER4
MOV ER8,ER0
MOV ER4,ER0
MOV ER12,ER2//三条MOV指令,在ER0,ER4,ER8中同时备份了目标地址,在ER2,ER12中同时备份了源地址
BC AL,22DE8h//若ER2为0,则跳转至22DE8
22DD6:
MOV ER0,ER4
L R2,【ER12】
ST R2,【ER4】//一对L和ST,以R2为“中转站”,实现了单字节复制
ADD ER0,#1
MOV ER4,ER0
ADD ER12,#1//源地址与目标地址同时后移1字节
L ER0,02h【FP】//FP即Frame Pointer,指ER14,这里动用了ER14备份的SP指针,将【FP+2】,即复制长度,读取进ER0
ADD ER0,#-1
ST ER0,02h【FP】//以ER0为“中转站”,实现了复制地址-1
22DE8:
MOV ER0,0
L ER2,02h【FP】//此处将复制长度读取至ER2
CMP ER0,ER2
BC LT,22DD6h//LT即小于,若ER0<ER2,即复制长度>0,则跳转至22DD6,继续复制一字节
MOV ER0,ER8
POP ER4
POP ER8
POP ER12
MOV SP,ER14
POP ER14//以上几行恢复了开始时备份的值
RT
值得一提的是,若调用的是187D0,由于没有PUSH ER0的指令,需要提前在“D0 87 01 00”后加上两字节的复制长度(注意小端);此外,此函数在结尾处有POP ER4,注意空出两字节,有需要时也可以充分利用,进行赋值
特别鸣谢:@casio2009 ,帮助我巩固了对此地址的理解;@amngis ,Xyzst循环一文让我对此地址的用法有了了解,各位读者也可以参考
附图:解析原稿


先来看@熠辉_子羿 在全过程解析像素编辑器中所提到的187CC的用法:memcpy(er4,er2) er0 long,从参数我们可以得知,该函数读取ER0的值作为复制长度,ER2的值作为源地址,ER4的值作为目标地址,并进行复制(小端序很重要)接下来,我将通过ROM片段对此地址进行详尽的解析来看ROM:187CC:PUSH ER0//这里困扰了我好久,需要结合后面才能看懂,各位读者目前只需要知道这条指令将ER0的值存入了内存,并覆盖了“CC 87”后面的两字节
MOV ER0,ER4//在ER0中备份目标地址
BL 02h:02DC4h//调用22DC4
POP ER0
POP ER4
POP PC
22DC4:
PUSH ER14
MOV ER14,SP//这里又困扰了我好久,这条地址的作用是在ER14中备份了SP指针指向的地址,由于上一条PUSH指令,此时SP=ER0所在地址-2
PUSH ER12
PUSH ER8
PUSH ER4
MOV ER8,ER0
MOV ER4,ER0
MOV ER12,ER2//三条MOV指令,在ER0,ER4,ER8中同时备份了目标地址,在ER2,ER12中同时备份了源地址
BC AL,22DE8h//若ER2为0,则跳转至22DE8
22DD6:
MOV ER0,ER4
L R2,【ER12】
ST R2,【ER4】//一对L和ST,以R2为“中转站”,实现了单字节复制
ADD ER0,#1
MOV ER4,ER0
ADD ER12,#1//源地址与目标地址同时后移1字节
L ER0,02h【FP】//FP即Frame Pointer,指ER14,这里动用了ER14备份的SP指针,将【FP+2】,即复制长度,读取进ER0
ADD ER0,#-1
ST ER0,02h【FP】//以ER0为“中转站”,实现了复制地址-1
22DE8:
MOV ER0,0
L ER2,02h【FP】//此处将复制长度读取至ER2
CMP ER0,ER2
BC LT,22DD6h//LT即小于,若ER0<ER2,即复制长度>0,则跳转至22DD6,继续复制一字节
MOV ER0,ER8
POP ER4
POP ER8
POP ER12
MOV SP,ER14
POP ER14//以上几行恢复了开始时备份的值
RT
值得一提的是,若调用的是187D0,由于没有PUSH ER0的指令,需要提前在“D0 87 01 00”后加上两字节的复制长度(注意小端);此外,此函数在结尾处有POP ER4,注意空出两字节,有需要时也可以充分利用,进行赋值
特别鸣谢:@casio2009 ,帮助我巩固了对此地址的理解;@amngis ,Xyzst循环一文让我对此地址的用法有了了解,各位读者也可以参考
附图:解析原稿












