[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 陆 - 条件分支 | 8. 家庭作业答案 - 5

注意:本文经过原作者授权转译,转载请标明出处

原文地址:http://mrjester.hapisan.com/04_MC68/Sect06Part08/Index.html

条件允许建议阅读原文,网上非中文资料还是较多,当作锻炼英文岂不美哉
翻译若有不足之处欢迎批评指正

译文:


"家庭电脑正在被赋予更多的新功能,包括处理之前总是会被狗吃掉的家庭作业" ---- 道格 拉森 (Doug Larson)

简介

这次的作业有些难度,需要仔细的追踪代码的每一步,追踪每个寄存器的值。不过,我丝毫不怀疑,即使你没有完全做对,至少对它的流程也了解的不错

答案

    move.w     #$0010, d0
    clr.l      d1
    move.w     #$0400, d4
    clr.l      d2
    move.w     #$1000, d3

  NotReached:
    addi.b     #$10, d2
    add.w      d0, d1
    cmp.w      d1, d4
    bgt.s      NotReached
    sub.w      d2, d1
    subi.w     #$1000, d3
    bpl.s      NotReached
    move.w     d1, d0
    swap       d0
    move.w     d3, d0

其中d0, d3d4的内容一开始都是 00000000

首先是前面的 5 条语句,很简单:

    move.w     #$0010, d0
    clr.l      d1
    move.w     #$0400, d4
    clr.l      d2
    move.w     #$1000, d3

它们执行之后:

d0 00000100
d1 00000000
d2 00000000
d3 00001000
d4 00000400

然后是

第一趟:

    addi.b     #$10, d2
    add.w      d0, d1

执行后d2的内容变成了 00000010 ,d1的内容变成了 00000100

接着

    cmp.w      d1, d4
    bgt.s      NotReached

d1的内容会和d4比较,0400 - 0100 = 0300CCR内容如下

C V Z N X
0 0 0 0 -

C0 (没有在的范围外发生进位),V0 (正数 - 正数 = 正数,符合数学规则,无溢出),Z0 (计算结果不是0),N0 (计算结果不是负数),X被忽略了 (CMP不会修改X)

指令BGT会因为目的操作数blue源操作数大而让 m68k 去分支跳转 (CCR逻辑表达式:Not(Z OR (N XOR V)),或者表示为¬Z ∧ ¬(N ⊕ V)等..),因为04000100要大 (ZNV都是0,满足BGT的跳转条件),所以 m68k 会去分支跳转到NotReached:标记处然后继续执行

所以继续循环这里:

第二趟:

    addi.b     #$10, d2
    add.w      d0, d1

执行后d2的内容变成了 00000020 ,d1的内容变成了 00000200

    cmp.w      d1, d4
    bgt.s      NotReached

d1的内容会和d4比较,0400 - 0200 = 0200,因为04000200要大,所以 m68k 会去分支跳转到NotReached:标记处然后继续执行

第三趟:

    addi.b     #$10, d2
    add.w      d0, d1

执行后d2的内容变成了 00000030 ,d1的内容变成了 00000300

    cmp.w      d1, d4
    bgt.s      NotReached

d1的内容会和d4比较,0400 - 0300 = 0100,因为04000300要大,所以 m68k 会去分支跳转到NotReached:标记处然后继续执行

第四趟:(本次循环最后一趟)

    addi.b     #$10, d2
    add.w      d0, d1

执行后d2的内容变成了 00000040 ,d1的内容变成了 00000400

    cmp.w      d1, d4
    bgt.s      NotReached

d1的内容会和d4比较,0400 - 0400 = 0000,因为0400并不比0400要大,所以 m68k 会忽略这次分支跳转,继续执行下面的指令

    sub.w      d2, d1

0400 - 0040 = 03C0d1的内容变成了 000003C0

    subi.w     #$1000, d3
    bpl.s      NotReached

1000 - 1000 = 0000d3的内容现在是 00000000

BPL指令会去分支跳转,因为计算结果是非负 (N的内容是0),所以跳转到NotReached:

    addi.b     #$10, d2
    add.w      d0, d1

执行后d2的内容变成了 00000050 ,d1的内容变成了 000004C0

    cmp.w      d1, d4
    bgt.s      NotReached

d1的内容会和d4比较,0400 - 04C0 = FF40,因为0400并不比04C0要大,所以 m68k 会忽略这次分支跳转,继续执行下面的指令

    sub.w      d2, d1

04C0 - 0050 = 0470
d1的内容是 00000470

    subi.w     #$1000, d3
    bpl.s      NotReached

0000 - 1000 = F000d3的内容现在是 0000F000

BPL此时不会分支跳转,因为计算结果是个负数 (N内容是1),于是 m68k 继续执行:

    move.w     d1, d0
    swap       d0
    move.w     d3, d0

0470d1中复制到d0里,于是d0的内容现在是 00000470

然后做寄存器内的交换 (SWAP),d0的内容现在是04700000

然后把d3中的放到d0里,于是d0的内容变成了0470F000

答案就是0470F000,如你所见,在这个过程中 m68k 做了多次的循环和跳转,这不仅表示了条件分支指令是如何工作的,同时还体现了他们协同起来可以把一些特殊的运算重复多次

目录
上一篇:[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 陆 - 条件分支 | 7. 无符号比较分支 (BCC, BHI, BLS, BCS)
下一篇:[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 柒 - 条件指令及其他 | 1. SEQ, SNE, SPL & SMI 指令

posted @ 2020-03-19 10:21  草帽过客  阅读(288)  评论(0编辑  收藏  举报