【问题标题】:What is the purpose of the instruction ROL.L d0, d0?指令 ROL.L d0, d0 的目的是什么?
【发布时间】:2021-08-29 09:10:27
【问题描述】:

我正在查看其他人编写的一些代码,并且有一次我找到了说明:

ROL.L d0, d0

现在,我知道这条指令允许我将位左移 n 位,例如:

ROL.L #$2, d0

它使我将数据寄存器 d0 中包含的长字的位向左移动两个位置,在左侧释放的任何位 (msb) 将重新出现在右侧 (lsb)。

确定这一点后,我推断出类似于我的问题中提到的指令:

ROL.L d0, d0

它使我将数据寄存器 d0 中包含的长字的位向左移动 d0 个位置。

事实上,情况并非如此。

我也尝试过英特尔微处理器,但似乎不支持这样的指令。 顺便说一句,在 64 位 INTEL 系统上,最大旋转是 255 个位置,而在 8088 微处理器上,一次只能旋转 1 个位置。

更新。 我想我会在我找到这个指令的地方包含过程代码。此过程生成伪随机数:

rand_func1
    move.l  #$12345678,d0
    addq.l  #5,d0
    rol.l   d0,d0
    move.l  d0,rand_func1+2  ; d0 = pseudo-random number
    rts 

【问题讨论】:

  • 关于“事实上,情况并非如此”:您能否详细说明您是如何得出这个结论的?你检查了d0 的什么输入值,你得到了什么输出,你期望什么?
  • 对于ROL.L d0, d0,CPU 使用d0 and 63 的旋转计数。因此,如果d0 寄存器包含的值是 64 的倍数,您将不会观察到该值的任何变化。
  • 即使在 8088 上,您也可以编写非常相似的 ROL CL, CL,它将字节大小的寄存器 CL(第一个操作数是目标)中的位旋转任意数量 在计数器寄存器CL 中(第二个操作数是源)。
  • @SepRoland:那么它是模 64 吗?我在我的问题中添加了一个细节,这是我找到指令的代码。
  • 对于ROL.LROR.L,结果实际上应该只取决于d0 and 31,因为将32 位整数旋转32+n 与旋转n 相同(我猜在那里是一些特殊情况下如何设置XC 标志,当移位32 与移位0 时,但我必须检查一下)。

标签: assembly motorola 68000


【解决方案1】:

根据@Sep Roland 告诉我的内容,我做了一些检查,这就是我得到的。

诸如 rol.l d0, d0 之类的指令将寄存器 d0 的位循环到 由 d0 中包含的值的模 64 留下。

对于 ROL.L d0, d0,CPU 使用 d0 和 63 的旋转计数。 因此,如果 d0 寄存器包含的值是 64 的倍数,则不会 观察值的任何变化。

模数是一个数除以另一个数的余数。 因此,一个数的模 64 是该数除以 64 的余数。 例如,65 的模 64 为 1,因为当您将 65 除以 64 时, 余数为 1。

代码示例:

move.l  #64,d0              
rol.l   d0,d0                   ; No changes, this is because:
                                ; Mod-64 of 64 is 0 because:
                                ; 64 / 64 = 1 remainder 0, because:
                                ; 64 x 0 = 0, so 64 - 64 = 0 
                                ;
                                ; so the code is equivalent to:
                                ; rol.l #0,d0, that is, no rotation

move.l  #65,d0              
rol.l   d0,d0                   ; Mod-64 of 65 is 1 because:
                                ; 65 / 64 = 1 remainder 64, because:
                                ; 64 x 1 = 64, so 65 - 64 = 1 
                                ;
                                ; so the code is equivalent to:
                                ; rol.l #1,d0, that is:
                                ; d0 = 65 = 00000000 00000000 00000000 01000001
                                ; once the code is executed:
                                ; rol.l #1,d0
                                ; d0 =      00000000 00000000 00000000 10000010 = 
                                ; = 82 hex
                                            
move.l  #120,d0             
rol.l   d0,d0                   ; Mod-64 of 120 is 56 because:
                                ; 120 / 64 = 1 remainder 56, because:
                                ; 64 x 1 = 64, so 120 - 64 = 56
                                ;
                                ; so the code is equivalent to:
                                ; rol.l #56,d0, that is:
                                ; d0 = 120 = 00000000 00000000 00000000 01111000
                                ; once the code is executed:
                                ; rol.l #56,d0 (if it could be done)
                                ; d0 =       01111000 00000000 00000000 00000000 = 
                                ; = 78000000 hex

【讨论】:

  • 或者更简单地说,您可以将 mod 64 视为只取二进制数字的低 6 位,65 & 63 = 0x41 & 0x3F = 1。这就是 CPU 在物理上是如何做到的;这就是为什么我们有 2 次方寄存器宽度的部分原因。
猜你喜欢
  • 2017-05-12
  • 2019-11-18
  • 2010-09-11
  • 2011-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-20
相关资源
最近更新 更多