我知道shl
指令就像mul
操作,shr
指令就像div
操作,它用于优化。
例如,shl eax, n
是一种更有效的实现方式,eax = (eax)*(2^n)
无需任何乘法指令。
现在我正在阅读rol
和ror
组装说明,我知道它是如何工作的,但我不知道一般旋转操作的重点是什么以及何时使用它?
我知道shl
指令就像mul
操作,shr
指令就像div
操作,它用于优化。
例如,shl eax, n
是一种更有效的实现方式,eax = (eax)*(2^n)
无需任何乘法指令。
现在我正在阅读rol
和ror
组装说明,我知道它是如何工作的,但我不知道一般旋转操作的重点是什么以及何时使用它?
位域的旋转或“循环移位”在密码学中经常用作非线性运算符,以实现他们所谓的“混淆”(试图打破明文和密文之间的所有统计联系)。
向左旋转的经典图形表示非常不言自明:
但是,它在纯算术中也有含义。它可以被看作是这样的乘法和加法(n
是位域的大小):
rotate-left (a, 0) = a
rotate-left (a, 1) = 2^(1).a + 2^(-n).a
rotate-left (a, 2) = 2^(2).a + 2^(1-n).a
...
rotate-left (a, n-1) = 2^(n-1).a + 2^(-1).a
rotate-left (a, n) = a
在 C 语言中,您可能仅使用按位运算符将其解释如下(请参阅维基百科关于循环移位的文章):
uint32_t rotl32 (uint32_t value, unsigned int count)
{
return ((value << count) | (value >> (32 - count)));
}
无论如何,旋转在大多数编程语言中经常被忽略。例如,您无法在 C 中轻松找到它。但是,这主要是因为:
然而,所有的汇编语言都提出了轮换运算符,因为它们可以成为许多低级优化的来源。
数据有损转移:shl eax,n : eax = ( eax*(2^n) ) %(2^32)
和shr eax,n : eax = floor( eax/(2^n) )
通常在单个数据值的快速未检查或逻辑绑定整数算术优化中找到,例如重复大小记录的地址偏移量。
数据无损旋转: rol eax,n : eax = shl eax,n or shr eax,32-n
通常用于密码学,检查算术优化或一串数据值的算术(搜索长乘法)或移动图形位掩码,例如rol eax,8
给出:and eax,0xFFFFFF00
eax *2^8
对于此数据值and eax,0x000000FF
并进位或溢出到下一个更重要的数据值。
其他建议的答案显然是旋转指令的主要应用;但是,我(可能有点独特)将它们用作非破坏性访问 32 位和 64 位寄存器上半部分中的数据的一种方式(主要是在处理打包数据同时反转视频游戏坐标数据时)。
由于没有专门执行该任务的指令,因此有必要将数据移位(破坏性)或旋转(非破坏性)到寄存器的下半部分,以便可以相应地访问/修改它。