注意:本文经过原作者授权转译,转载请标明出处
原文地址:http://mrjester.hapisan.com/04_MC68/Sect05Part03/Index.html
条件允许建议阅读原文,网上非中文资料还是较多,当作锻炼英文岂不美哉
翻译若有不足之处欢迎批评指正
译文:
"在我的身后,那荒芜破败的树枝在嘎吱作响" ---- 古斯塔夫 马勒 (Gustav Mahler, 1860-1911),奥地利作曲家及指挥家
简介
BRA (BRanch Always) - 无条件分支
这条指令会把目的操作数
的内容加到PC
上,然后再从PC
中的位置继续执行程序
例子
这和JMP
指令非常相似,除了一点点的区别。下面是和上一节差不多的例子,只是把里面的JMP
指令换成了BRA
指令:
move.w d0, d1
add.w d1, d1
add.w d1, d0
bra.s SkipCode
add.w d2, d3
asr.w #$04, d0
SkipCode:
move.w d0, d2
中间那个就是从上到下崭崭新的BRA
指令:
bra.s SkipCode
这一串指令所做的事情也和上一节很像:
他们之间主要的区别就是内存使用还有处理时间,BRA
指令会比JMP
指令执行速度更快,而且占用更少的内存,可以节省你的内存空间以及提升执行效率
现在你们可能会问了,"既然BRA
指令又小又快,那JMP
指令的存在又有什么意义呢?"
问得好,先让我们来康康内存:
偏移量 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
... | ||||||||||||||||
00244200 | 32 | 00 | D2 | 41 | D0 | 41 | 60 | 04 | D6 | 42 | E8 | 40 | 34 | 00 | 00 | 00 |
00244210 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 |
00244220 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 |
00244230 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 |
... |
如你所见,既然BRA
指令 (6004
) 是JMP
指令的 1/3 大小,60
表示bra.s
,04
是加到PC
上的值
附加的这个值 (偏移量,见相对寻址) 只有一个字节
大小,而且它是个有符号数
,也就是说这条指令可以向前分支最多的字节是7E
,而它向后分支最远是80
,所以答案很明显了,bra.s
不能像JMP
指令那样跳到任何位置
刚刚说的都是bra.s
,其中的.s
表示的是short
,即短整型
,当然还有指令可以使用的另一种长度bra.w
,其中的.w
表示的是字
:
move.w d0, d1
add.w d1, d1
add.w d1, d0
bra.w SkipCode
add.w d2, d3
asr.w #$04, d0
SkipCode:
move.w d0, d2
偏移量 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
... | ||||||||||||||||
00244200 | 32 | 00 | D2 | 41 | D0 | 41 | 60 | 00 | 00 | 06 | D6 | 42 | E8 | 40 | 34 | 00 |
00244210 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 |
00244220 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 |
00244230 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 |
... |
在这种情况下,分支指令比之前要长了一倍 (60000006
),不过仍然要比JMP
指令更小更快。60
表示bra
,紧接其后的00
表示.w
,然后0006
是加到PC
上的值
疑问:似乎在跳转之前,读取指令之后,
PC
只是+2
而不是加了这条bra
指令的长度,然后再+6
,emmmmm...
附加的这个值有一个字
大小,也是个有符号数
,也就是说这条指令可以向前分支最多的字节是7FFE
,而它向后分支最远是8000
疑问:为什么向前跳转最多是
7FFE
而不是7FFF
????
如你所见,它的寻址范围比bra.s
要更大一些,但仍然要比JMP
指令小
用法
在有些时候你可能想要用最快最小的指令,下面是一张简明的表格表示了跳转和分支指令以及它们的跳转范围:
指令 |
内存形式/长度 |
范围 |
---|---|---|
bra.s | 60 ?? | 向前或向后7E 字节 |
bra.w | 60 00 ?? ?? | 向前或向后7FFE 字节 |
jmp | 4E F9 00 ?? ?? ?? | 000000 - FFFFFF (无限制) |
bra.s
是这三个中最小最快的,不过它的跳转范围很受限,而JMP
允许你跳到任何位置,然而它占用更多的内存空间而且会占用 m68k 更长的处理时间
一般来说,如果你想去优化你的代码,优先级是:
bra.s -> bra.w -> jmp
先去尝试使用bra.s
,如果跳转的位置太远了,就用bra.w
,如果还要更远的话,就用jmp
目录
上一篇:[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 伍 - 程序流程控制 | 2. JMP (跳转) 指令
下一篇:[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 伍 - 程序流程控制 | 4. SP (Stack Pointer) 堆栈指针寄存器
[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 伍 - 程序流程控制 | 3. BRA (分支) 指令