[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 肆 - 正负 指令 | 7. ROL 和 ROR 指令

注意:本文经过原作者授权转译,转载请标明出处

原文地址:http://mrjester.hapisan.com/04_MC68/Sect04Part07/Index.html

条件允许建议阅读原文,网上非中文资料还是较多,当作锻炼英文岂不美哉
翻译若有不足之处欢迎批评指正

译文:

这么多年来的经验告诉我,不管你在球场的哪个位置,都要时刻做好投球的准备" ---- 克里 莱都 (Cory Lidle, 1972-2006),美国纽约洋基队投手 (垒球)

简介

现在我们已经了解了移位,那么接下来再康康 位旋转 (循环移位),先用字节 C4来做例子:

    1100 0100

当向左循环移位 (旋转) 时,所有的都会向左移动,而所有移出这个字节范围的位都会从右边填补进来,就像下图所示:

[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 肆 - 正负 指令 | 7. ROL 和 ROR 指令

如果我们把C4向左循环移位一位,会得到:

  v 1000 1001 <
  > > > > > > ^ 

就变成了十六进制的89,正如你所见,所有的都被向左移动了,然后MSB (最高有效位) 被移出了字节范围然后被放到了最右边LSB (最低有效位) 的位置,如果我们再循环左移两次的话:

  v 0010 0110 <
  > > > > > > ^ 

可以看到原本最左边的两位10被移出了字节范围,然后补充到了最右边

对于循环右移来说也有类似的规则,任何移出字节范围的都会被填充到最左边,就像下图所示:

[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 肆 - 正负 指令 | 7. ROL 和 ROR 指令

同样再以字节 C4做例子:

    1100 0100

然后做循环右移2

  > 0011 0001 v
  ^ < < < < < < 

所有的都被向右移动了,然后LSB的那些移出的位被放到MSB处了

这些就是循环移位的一些基本概念

ROL 指令

ROL (ROtate Left (without extended)) - 循环左移 (无扩展)

这条指令会把目的操作数里的做循环左移,循环左移的位数取决于源操作数

例子

    rol.b      #$02, d0

这条指令会把d0中的字节向左循环移动02位。现在我们假定d0的内容是009F00B2,由于移动的是字节,所以只有B2会被修改,B2的二进制是:

    1011 0010

在循环左移02位之后,会得到:

  v 1100 1010 <
  > > > > > > ^ 

1100 1010在十六进制是CA,保存到d0里,所以d0的内容就变成了009F00CA

再来康康另一个例子:

    rol.l      #$04, d2

这条指令会把d2中的长字向左循环移动04位。现在我们假定d2的内容是76543210,二进制是:

    0111 0110 0101 0100 0011 0010 0001 0000

在循环左移04位之后,会得到:

  v 0110 0101 0100 0011 0010 0001 0000 0111 <
  > > > > > > > > > > > > > > > > > > > > > ^ 

此时d2的内容是65432107

当使用数据寄存器作为源操作数时,移位和循环移位之间有些细微的差别,比如:

    rol.l      d0, d2

就像我之前提到的那样,对于普通的移位来说,最大的移位位数取决于你的指令指定的长度

  • 字节 (.b)最大允许移动$08
  • (.w)最大允许移动$10
  • 长字 (.l)最大允许移动$1F位 (此处应为$20位?)

而对于循环移位来说,并没有最大移位长度 (技术上来说):

  • 使用字节 (.b) 并且超出$07位时,移位位数会自动从$00重新计算
  • 使用 (.w) 并且超出$0F位时,移位位数会自动从$00重新计算
  • 使用长字 (.l) 并且超出$1F位时,移位位数会自动从$00重新计算

所以当循环移位一个字节 09 时,和循环移动它01 是等价的,同理0A 02 等价,以此类推

针对内存的循环移位的规则和针对内存的移位规则是一样的,具体请参见之前的小节

ROR 指令

ROR (ROtate Right (without extended)) - 循环右移 (无扩展)

这条指令会把目的操作数里的做循环右移,循环右移的位数取决于源操作数

例子

    ror.b      #$02, d0

这条指令会把d0中的字节向右循环移动02位。现在我们假定d0的内容是009F00B2,由于移动的是字节,所以只有B2会被修改,B2的二进制是:

    1011 0010

在循环右移02位之后,会得到:

  > 1010 1100 v
  ^ < < < < < < 

1010 1100在十六进制是AC,保存到d0里,所以d0的内容就变成了009F00AC

再来康康另一个例子:

    ror.w      #$04, d2

这条指令会把d2中的向右循环移动04位。现在我们假定d2的内容是0000BA98,只有一个会被移动,所以BA98的二进制是:

    1011 1010 1001 1000

在循环右移04位之后,会得到:

  > 1000 1011 1010 1001 v
  ^ < < < < < < < < < < < 

此时d2的内容是00008BA9

同样内存的循环移位也请参见之前关于内存移位的规则

目录
上一篇:[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 肆 - 正负 指令 | 6. LSL, LSR, ASL 和 ASR 指令
下一篇:[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 肆 - 正负 指令 | 8. MULU 和 MULS 指令

上一篇:032- for循环语句


下一篇:阿里巴巴首次揭秘电商知识图谱AliCoCo!淘宝搜索原来这样玩!