街机模拟游戏逆向工程(HACKROM)教程:[15]68K汇编-测试对比指令

发布时间:2024年01月21日

简介

测试或对比指令会检查源操作数 和 目标操作数的某些特定条件的状态,然后设置相对应的CCR的某些状态标志,这些指令通常不会对源操作数和目标操作数产生改变。

cmp指令

该指令通过用目标操作数减去源操作数的结果来获得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

?我们可以看到,在执行中,该指令可能会同时对多个标志位产生影响。而该指令可以检测两个数据间的各种对比情况。

tst指令

该指令会把目标操作数与0作比较然后根据结果来改变CCR状态标志,目标操作数的内容不会被改变。

TST??? Test an Operand 测试一个操作数
??? 运算:??? 目的操作数测试 置入 标志寄存器
??? 语法:??? TST <ea>
??? 操作数长度:B、W、L
??? 条件码(标志位):??? X — 不受影响。
??????????????????????????????????????? N — 如果操作数为负数则置1;其它情况置0。
??????????????????????????????????????? Z — 如果操作数为零则置1;其它情况置0。
??????????????????????????????????????? V — 置0。
??????????????????????????????????????? C — 置0。

可以看到,该指令只对两个标志位产生影响。也就是说,该指令可以用来检查一个数值是否为零,和是否为负。

BTST 指令

该指令会测试目的操作数中的某一位看看它是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的状态标志,有的时候,我们为了精简程序,也可以在一些情况下不使用这些测试和对比指令,从而减少代码量。

文章来源:https://blog.csdn.net/m0_50114967/article/details/135484953
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。