测试或对比指令会检查源操作数 和 目标操作数的某些特定条件的状态,然后设置相对应的CCR的某些状态标志,这些指令通常不会对源操作数和目标操作数产生改变。
该指令通过用目标操作数减去源操作数的结果来获得CCR的状态,在执行后,源操作数 和 目标操作数的内容保持不变。也就是说,该指令的执行,只会改变对应的CCR标志位。
我们查看一下说明,看该指令可以对哪些标志位产生影响
CMP??? Compare 比较
??? 运算:??? 目的操作数-原操作数 置入 条件位
??? 语法:??? CMP <ea>,Dn
??? 操作数长度:B、W、L
??? 条件码(标志位):??? X — 不受影响。
??????????????????????????????????????? N — 如果结果为负数则置1;其它情况置0。
??????????????????????????????????????? Z — 如果结果为零则置1;其它情况置0。
??????????????????????????????????????? V — 如果发生溢出则置1;其它情况置0。
??????????????????????????????????????? C — 如果有进位/借位则置1;其它情况置0。
?我们可以看到:
X — 不受影响。
N — 如果结果为负数则置1;其它情况置0。
Z — 如果结果为零则置1;其它情况置0。
V — 如果发生溢出则置1;其它情况置0。
C — 如果有进位/借位则置1;其它情况置0。
我们可以来测试各种情况下对标志位产生的影响:
ORG $100
START:
move.b #$08,d0
cmpi.b #$09,d0 有进/借位 ,无溢出 ,非0 ,为负
cmpi.b #$07,d0 无进/借位 ,无溢出 ,非0 ,非负
cmpi.b #$08,d0 无进/借位 ,无溢出 ,为0 ,非负
move.b #$81,d0
cmpi.b #$80,d0 无进/借位 ,有溢出 ,非0 ,为负
END START
?我们可以看到,在执行中,该指令可能会同时对多个标志位产生影响。而该指令可以检测两个数据间的各种对比情况。
该指令会把目标操作数与0作比较然后根据结果来改变CCR状态标志,目标操作数的内容不会被改变。
TST??? Test an Operand 测试一个操作数
??? 运算:??? 目的操作数测试 置入 标志寄存器
??? 语法:??? TST <ea>
??? 操作数长度:B、W、L
??? 条件码(标志位):??? X — 不受影响。
??????????????????????????????????????? N — 如果操作数为负数则置1;其它情况置0。
??????????????????????????????????????? Z — 如果操作数为零则置1;其它情况置0。
??????????????????????????????????????? V — 置0。
??????????????????????????????????????? C — 置0。
可以看到,该指令只对两个标志位产生影响。也就是说,该指令可以用来检查一个数值是否为零,和是否为负。
该指令会测试目的操作数中的某一位看看它是0还是1,具体是哪一位取决于源操作数,然后结果会被放到Z状态标志中。
BSET??? Test Bit and Set 测试并置1某个位
??? 运算:??? 测试(目的操作数的位号)置入 Z ;
??????? 1 置入 目的操作数的该位
??? 语法:??? BSET Dn,<ea>
?????????????????? BSET #<data>,<ea>
??? 操作数长度:B、L
??? 条件码(标志位):??? Z — 如果结果为零则置1;其它情况置0。
??????????????????????????????????????? 其它位不受影响。
要测试该指令,我们首先需要知道,一个单字节数值有8个位,简单来说,我们可以把一个单字节数值转换为二进制,就可以查看对应的每个位了,比如:
位 7 6 5 4 3 2 1 0
01 0 0 0 0 0 0 0 1
05 0 0 0 0 0 1 0 1
08 0 0 0 0 1 0 0 0
7F 0 1 1 1 1 1 1 1
90 1 0 0 1 0 0 0 0
FE 1 1 1 1 1 1 1 0
我们可以看到,
当数值为$01时,只有第0位的值为1。
当数值为$05时,第0位和第2位的值为1。
据此,我们也可以推断出当数值为$00时,所有位都为0,当数值为$FF时,所有的位都为1。
我们用例子来说明该指令的作用原理:
btst #$02, d0
当d0 = $01时,数值的第$2位为0,结果为0 ,这时Z标志位会被设为1。
当d0 = $05时,数值的第$2位为1,结果不为0,这时Z标志位会被设为0。
这些测试和对比指令,通常会和一些条件跳转/分支的指令连在一起使用 (比如BEQ),同时,我们需要注意的是,许多指令都会去设置修改CCR的状态标志,有的时候,我们为了精简程序,也可以在一些情况下不使用这些测试和对比指令,从而减少代码量。