你的图的左边,寄存器的PSW的RS值为1,说明你这个函数或者上级函数using 1了。
而你右边图的C:135A行直接把 07的值放到了@R0页就是1C地址的RF_BufRam[0],而参考你前面有个if里面使用了RF_DataRam[0], (你的汇编没有抓到此处),我估计是RF_DataRam[0]被分配到了R7,下面第一次用的时候直接从R7取了。
可是在PSW的RS不是0的情况下,R7和07地址不是一个。
解决方案1:
你把这个函数也加上using 1,你会发现C:0x135A的反汇编会变为 MOV @R0,0x0F
解决方案2:
禁止使用R7的别名AR7,
2.1 把Project、Options、C51 里面的 Don't use absolute register accesses勾上,这样所有的函数都没有办法使用别名了。对于8051 MOV R0,R1 这种指令就从 MOV R0,0x01这么一条变为经过其它寄存器中转的两条了。比如XCHG A,R2 ; XCHG A,R1 ; 或者 MOV A,R2; MOV R1,A 也是两条指令,不过破坏了A。
2.2 在Project Options 的Misc Controls里面填上 NOAREGS ,缺点同上。
2.3 在这个函数的前面加上单独pragama加上 NOAREGS,这样其它函数的效率不变。
2.4 ... ...
对于很多新手,Keil(有些是8051架构的)的很多坑都要挨个踩,比如using,比如pdata越界,比如链接不上用null,比如堆栈空间不计算,比如xxxxxx。ARM那种统一编址的问题会少很多。
对于using的这个问题,我有个小工具,可以根据静态调用树扫出来。 但是函数指针的就不行了,不完善,所以就不能给大家分享了。除了寄存器bank,像有些产品的sfr bank、code bank、pdata bank等等也都有容易出错的地方,都需要一个个的小工具来帮助。
|