注意:本文经过原作者授权转译,转载请标明出处
原文地址: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, d3和d4的内容一开始都是 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 = 0300,CCR内容如下
| C | V | Z | N | X |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | - |
C是0 (没有在字的范围外发生进位),V是0 (正数 - 正数 = 正数,符合数学规则,无溢出),Z是0 (计算结果不是0),N是0 (计算结果不是负数),X被忽略了 (CMP不会修改X)
指令BGT会因为目的操作数比blue源操作数大而让 m68k 去分支跳转 (CCR逻辑表达式:Not(Z OR (N XOR V)),或者表示为¬Z ∧ ¬(N ⊕ V)等..),因为0400比0100要大 (Z,N和V都是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,因为0400比0200要大,所以 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,因为0400比0300要大,所以 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 = 03C0 ,d1的内容变成了 000003C0
subi.w #$1000, d3
bpl.s NotReached
1000 - 1000 = 0000,d3的内容现在是 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 = F000,d3的内容现在是 0000F000
BPL此时不会分支跳转,因为计算结果是个负数 (N内容是1),于是 m68k 继续执行:
move.w d1, d0
swap d0
move.w d3, d0
把0470从d1中复制到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 指令