[转译][马基 杰斯特(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
, 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 指令