[转译][马基杰斯特(MarkeyJester)摩托罗拉68000入门教程]肆-正负指令6。。。

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

[转译][马基杰斯特(MarkeyJester)摩托罗拉68000⼊门教程]
肆-正负指令6。

注意:本⽂经过原作者授权转译,转载请标明出处
原⽂地址:
条件允许建议阅读原⽂,⽹上⾮中⽂资料还是较多,当作锻炼英⽂岂不美哉
翻译若有不⾜之处欢迎批评指正
译⽂:
"我们正⽣活在⼀个观念转变的时代。

⽗母不负责任,家庭分崩离析。

" ---- ⼽登欣克利 (Gordon B. Hinckley, 1910-
2008),美国宗教领袖,作家
简介
在上⼀节我们了解了"移位",以及"逻辑移位"和"算术移位"的区别。

在这⼀节我们来康康⼀些具体的移位指令,由于它们⼤多拥有类似的使⽤规则,所以我把它们放在了同⼀节⾥⾯⼀并来讲
如果你们觉得看这⼀节有困难的话,请给我提意见或是建议,我将会尝试着去改进
我的邮箱地址在可以找得到
LSL 指令
LSL (Logical Shift Left) - 逻辑左移
这条指令会把⽬的操作数中的内容做逻辑左移,移动的位数取决于源操作数
例⼦
先⽤我常常使⽤的那个最基本的例⼦吧:
lsl.b#$02, d0
这条指令会把d0中的字节向左移动02位。

现在我们假定d0的内容是000004B2,由于移动的是字节,所以只有B2会被修改,B2的⼆进制是:
1011 0010
在左移02位之后,会得到:
< 1100 1000 <
1100 1000在⼗六进制是C8,保存到d0⾥,所以d0的内容就变成了000004C8
再来康康另⼀个例⼦:
lsl.w#$04, d2
这条指令会把d2中的字向左移动04位。

现在我们假定d2的内容是00F0FEDC,由于移动的是字,所以只有FEDC会被修改,FEDC的⼆进制是:
1111 1110 1101 1100
在左移04位之后,会得到:
< 1110 1101 1100 0000 <
FEDC变成了EDC0,所以此时d2的内容是00F0EDC0
移位的位数以及语法
注意:这些规则同样对于LSL,LSR,ASL,ASR,ROL和ROR指令都适⽤
⽴即数移位
最⼤的可以操作的移位位数是08位,最⼩的是01位,如果你想要移位位数超过08位,那你只需要把指令拆成两个指令先后执⾏即可,⽐如想要左移0C位:
lsl.l#$08, d0
lsl.l#$04, d0
从上⾯可以看出,第⼀条指令先左移了08位,然后第⼆条指令⼜左移了04位,加起来就是总共左移了0C位。

当然了,是存在其他的更快捷的指令,不过最好是留在以后再说
现在如果你想要仅仅左移01的话,只需要像这样写:
lsl.w d0
此时汇编程序会把指令⾃动转换位:
lsl.w#$01, d0
有些⼈习惯于不写#$01,⼤概是想要省去⼀些打字的⼒⽓,谁知道呢。

对于我个⼈来说,我总是会写上#$01。

不过这要看你⾃⼰的习惯,写不写事实上是⼀样的
寄存器移位
你可以使⽤⼀个数据寄存器⽤来表⽰移位的位数,⽐如:
lsl.l d0, d1
在这个例⼦中,d1的内容会被左移,位数取决于d0⾥的数字,假设d0的内容是0000010F
对源操作数来说,只有⼀个字节会被当做移位的位数,因为d0的内容是0000010F,所以其中的0F会被当做位数。

所以d1中的长字会被左移0F位
你可以移位的最⼤位数取决于你的指令所使⽤的长度:
字节 (.b)最⼤允许移动$08位
字 (.w)最⼤允许移动$10位
长字 (.l)最⼤允许移动$1F位 (此处应为$20位?)
如果源操作数的字节要⽐最⼤的移位位数要⼤的话,就会默认按照最⼤的移位位数来移位,⽐如:
lsl.b d0, d1
如果d0⾥的字节是09或是更⼤的数的话,那么d1会按照.b的最⼤移位位数⽽只移动08位
内存移位
当在数据寄存器上使⽤移位指令时,你可以⽤字节,字或是长字长度的指令,⽽且可以⼀次移动超过01位,但是对于内存移位来说,你只能使⽤字的长度,⽽且只能⼀次移动01位:
lsl.w$00FF0000
lsl.w $20(a0)
lsl.w (a0)+
lsl.w -(a0)
注意:在内存移位中,没有源操作数,如果你这样写的话:
lsl.w#$01, $00FF0000
lsl.w#$01, $20(a0)
lsl.w#$01, (a0)+
lsl.w#$01, -(a0)
你的汇编程序有可能会报错,不过有些汇编程序可能没那么敏感,不过最好在内存移位时还是不要指定移位长度01
当然,你也不能直接把这个指令直接⽤在地址寄存器上:
lsl.w#$04, a0✖
lsl.l a0✖
lsl.l d0, a0✖
LSR 指令
LSR (Logical Shift Right) - 逻辑右移
这条指令会把⽬的操作数中的内容做逻辑右移,移动的位数取决于源操作数
例⼦
lsr.b#$02, d0
这条指令会把d0中的字节向右移动02位。

现在我们假定d0的内容是000004B2,由于移动的是字节,所以只有B2会被修改,B2的⼆进制是:
1011 0010
在右移02位之后,会得到:
> 0010 1100 >
0010 1100在⼗六进制是2C,保存到d0⾥,所以d0的内容就变成了0000042C
再来康康另⼀个例⼦:
lsr.w#$04, d2
这条指令会把d2中的字向右移动04位。

现在我们假定d2的内容是00F0FEDC,由于移动的是字,所以只有FEDC会被修改,FEDC的⼆进制是:
1111 1110 1101 1100
在右移04位之后,会得到:
> 0000 1111 1110 1101 >
FEDC变成了0FED,所以此时d2的内容是00F00FED
ASL 指令
ASL (Arithmetic Shift Left) - 算术左移
这条指令会把⽬的操作数中的内容做算术左移,移动的位数取决于源操作数
例⼦
这和LSL指令⼤致相同:
asl.b#$02, d0
这条指令会把d0中的字节向左移动02位。

现在我们假定d0的内容是000004B2,由于移动的是字节,所以只有B2会被修改,B2的⼆进制是:
1011 0010
在左移02位之后,会得到:
< 1100 1000 <
1100 1000在⼗六进制是C8,保存到d0⾥,所以d0的内容就变成了000004C8
由于逻辑左移和算术左移的结果是⼀样的,所以这条指令和LSL指令的效果是⼀样的
其实当然还是有区别的,LSL指令会清除V状态字,⽽ASL指令会根据结果来设置或是清除V状态字,然⽽V状态字是CCR (Conditional Code Register, 状态寄存器) 的⼀部分,我们会在之后教程⾥会提到的⼀个快速对照表⾥详细的解释,所以现在搞不清楚没关系
ASR 指令
ASR (Arithmetic Shift Right) - 算术右移
这条指令会把⽬的操作数中的内容做算术右移,移动的位数取决于源操作数
例⼦
这和LSL指令⼤致相同:
asr.b#$02, d0
这条指令会把d0中的字节向左移动02位。

现在我们假定d0的内容是000004B2,由于移动的是字节,所以只有B2会被修改,B2的⼆进制是:
1011 0010
在左移02位之后,会得到:
> 1110 1100 >
1110 1100在⼗六进制是EC,保存到d0⾥,所以d0的内容就变成了000004EC
注意:MSB之前是1,所以移位之后它仍是1
再来康康另⼀个例⼦:
asr.w#$04, d2
这条指令会把d2中的字向右移动04位。

现在我们假定d2的内容是00F07EDC,由于移动的是字,所以只有7EDC会被修改,7EDC的⼆进制是:
0111 1110 1101 1100
在右移04位之后,会得到:
> 0000 0111 1110 1101 >
7EDC变成了07ED,所以此时d2的内容是00F007ED
由于MSB之前是0,所以移位之后它仍是0。

相关文档
最新文档