本帖最后由 hfbjjs 于 2011-3-8 04:26 编辑
二说: 非常好的 SN 比较指令 cmprs
之前,我在本论坛写过帖子: 非常好的 SN 比较指令 cmprs ,这恐怕是一个被许多人误以为仅仅是比较 2 个寄存器内数值大小的指令,实则不是的!
单片机程序里,经常需要知道 2 个数的大小,有时候,还不希望影响被比较的 2 个原始寄存器的内容,比较之前与比较之后,参与比较的寄存器丝毫没有影响!
又由于日常单片机的数据里,一个字节的 8 位=255 实在不够用,这样,基本上大多数时候处理的就是双字节=16 位数值. 最大=65535! 这个数基本上涵盖了日常仪器仪表,物理量,化学量等等领域的大部分要求!------下面就以双字节的基本数据再说一下 CMPRS 指令的应用问题!
一句话: CMPRS 指令不仅仅可以比较出 2 组数是否相等,而且可以比较出 2 组数据的大小!
例如: 比较 M0H_M0L 与 M1H_M1L 是否相等?谁大:? 谁小? .而且不能破坏它们本身的数值.
我们最容易想到的就是使用减法:
如:
MOV A,M0L
SUB A,M1L
MOV R,A ;注意这个指令,不影响任何标志! ------下面解释为什么添加这个指令.
MOV A,M0H
SBC A,M1H
此时,只要看看 FC 就知道谁大谁小了!-----而是否相等呢? 看不出来! 因为 FC 仅仅可以知道 ≥ 和 < ,不能知道是否 = .
这就是为什么上面添加一条 " MOV R,A " 的用途了 !
在 SBC A,M1H 之后,如果 A=0 则 FZ=1 ,再 R = 0 的话,来一次 MOV A,R 就知道 FZ 了. 这两步 FZ 如果都是=1,说明结果是 0 ,则是相等了! ------ 这样处理,是不是有点罗嗦和麻烦 ?
再看看使用 CMPRS 指令会如何?
MOV A,M0H ;与使用减法不同,使用 CMPRS 要从高字节开始.有可能省去比较下一次的比较!--- 如果 M0H≠M1H 一步就知道大小!
COMPRS A,M1H
JMP Z_FC ; M0H≠M1H 跳走,一步就知道大小!
MOV A,M0L
COMPRS A,M1L
JMP Z_FC ; M0L≠M1L 跳走,二步知道大小!
JMP Z_FZ ;上面完全相等,跳走到这里! M0=M1 !
Z_FC :
BTS1 FC
JMP Z_M0X ;FC=0 , M0<M1
JMP Z_M0D ;FC=1 ,M0DD>M1
这一段干净利落!三种结果非常分明!丝毫没有影响 M0,M1 2 组数据的内容!
说白了,就是 CMPRS 会根据比较结果影响标志 FZ 和 FC ,而且 FZ 是隐含的自动判断!相等跳过是也!
原理解释: CMPRS 能够比较出 > ,= ,< 来!
例如:
设: M0=M1 ,此时使用 CMPRS 后, FZ=1 ,C=1.
设: M0>M1 ,此时使用 CMPRS 后, FZ=0, C=1,
设: M0<M1 ,此时使用 CMPRS 后, FZ=0, C=0,
看看 FZ 与 C ,三种结果是非常分明的! ----- 不妨自己去体验试一下.
恰好, 51 也有这条指令,效果相似,非常好用!它不仅仅不会影响原来的寄存器内容!而且可以节省许多指令.
仅供参考! |
|