[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 肆 - 正负 指令 | 6. LSL, LSR, ASL 和 ASR 指令
注意:本文经过原作者授权转译,转载请标明出处
原文地址:http://mrjester.hapisan.com/04_MC68/Sect04Part06/Index.html
条件允许建议阅读原文,网上非中文资料还是较多,当作锻炼英文岂不美哉
翻译若有不足之处欢迎批评指正
译文:
"我们正生活在一个观念转变的时代。父母不负责任,家庭分崩离析。" ---- 戈登 欣克利 (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
目录
上一篇:[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 肆 - 正负 指令 | 5. 移位
下一篇:[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 肆 - 正负 指令 | 7. ROL 和 ROR 指令
浙公网安备 33010602011771号