Masm64:整体位处理-移位指令

1. 逻辑左移指令(SHL)

功能:

将操作数的所有位向左移动指定的位数。空出的低位用0填充,移出的高位部分如果是算术左移可能进入进位标志CF(对于有符号数操作可能会影响数的符号和大小)。

操作数类型和格式:

操作数可以是寄存器或者内存单元。格式为SHL 操作数, 移位次数,其中移位次数可以是立即数(取值范围为0 - 63)或者CL寄存器(CL中的值表示移位次数,取值范围为0 - 63)。

立即数移位:shl rax, 3,将rax寄存器中的值向左移动3位,相当于将rax乘以8(因为左移n位相当于乘以2的n次方)。

使用CL寄存器确定移位次数:假设CL中已经存储了移位次数2,shl rbx, cl,将rbx寄存器中的值向左移动CL中指定的2位。

2. 逻辑右移指令(SHR)

功能:

将操作数的所有位向右移动指定的位数。空出的高位用0填充,移出的低位部分如果是算术右移可能进入进位标志CF。

操作数类型和格式:

与SHL指令类似,操作数可以是寄存器或者内存单元,格式为SHR 操作数, 移位次数,移位次数可以是立即数或者CL寄存器。

立即数移位:shr eax, 2,将eax寄存器中的值向右移动2位,相当于将eax除以4(因为右移n位相当于除以2的n次方,对于无符号数)。

使用CL寄存器确定移位次数:如果CL的值为3,shr [var], cl,这里var是一个已定义的内存变量,将内存变量var中的值向右移动CL中指定的3位。

3. 算术左移指令(SAL)

功能:

在功能上和逻辑左移指令SHL相同,都是将操作数的所有位向左移动指定的位数,空出的低位用0填充。但是在语义上,SAL主要用于有符号数的操作,表示算术左移。

操作数类型和格式:

操作数可以是寄存器或者内存单元,格式为SAL 操作数, 移位次数,移位次数可以是立即数或者CL寄存器。

立即数移位:sal rcx, 4,将rcx寄存器中的有符号数向左移动4位。

使用CL寄存器确定移位次数:假设CL = 1,sal [num], cl,这里num是一个已定义的有符号数内存变量,将其向左移动CL中的1位。

4. 算术右移指令(SAR)

功能:

将操作数的所有位向右移动指定的位数。空出的高位用操作数的符号位填充(即如果操作数是正数,高位补0;如果是负数,高位补1),移出的低位部分进入进位标志CF。这一操作保持了有符号数在进行右移操作时的符号不变。

操作数类型和格式:

操作数可以是寄存器或者内存单元,格式为SAR 操作数, 移位次数,移位次数可以是立即数或者CL寄存器。

立即数移位:sar rax, 1,将rax寄存器中的有符号数向右移动1位。如果rax为负数,高位会补1;如果为正数,高位补0。

使用CL寄存器确定移位次数:若CL = 2,sar [value], cl,这里value是一个有符号数内存变量,将其向右移动CL中指定的2位。

5. 循环左移指令(ROL)

功能:

将操作数的所有位向左循环移动指定的位数。即移出的高位部分又重新移回到低位部分,形成循环。

操作数类型和格式:

操作数可以是寄存器或者内存单元,格式为ROL 操作数, 移位次数,移位次数可以是立即数或者CL寄存器。

立即数移位:rol rbx, 3,将rbx寄存器中的值向左循环移动3位。

使用CL寄存器确定移位次数:假设CL = 4,rol [data], cl,这里data是一个已定义的内存变量,将其向左循环移动CL中指定的4位。

6. 循环右移指令(ROR)

功能:

将操作数的所有位向右循环移动指定的位数。即移出的低位部分又重新移回到高位部分,形成循环。

操作数类型和格式:

操作数可以是寄存器或者内存单元,格式为ROR 操作数, 移位次数,移位次数可以是立即数或者CL寄存器。

立即数移位:ror eax, 2,将eax寄存器中的值向右循环移动2位。

使用CL寄存器确定移位次数:若CL = 5,ror [var1], cl,这里var1是一个已定义的内存变量,将其向右循环移动CL中指定的5位。

7. 带进位循环左移指令(RCL)

功能:

将操作数的所有位连同进位标志CF一起向左循环移动指定的位数。在移动前,CF的值成为操作数的新的最低位,而操作数移出的最高位成为新的CF值。

操作数类型和格式:

操作数可以是寄存器或者内存单元,格式为RCL 操作数, 移位次数,移位次数可以是立即数或者CL寄存器。

立即数移位:rcl rdx, 1,将rdx寄存器中的值连同进位标志CF向左循环移动1位。

使用CL寄存器确定移位次数:假设CL = 3,rcl [num1], cl,这里num1是一个已定义的内存变量,将其连同进位标志CF向左循环移动CL中指定的3位。

8. 带进位循环右移指令(RCR)

功能:

将操作数的所有位连同进位标志CF一起向右循环移动指定的位数。在移动前,CF的值成为操作数的新的最高位,而操作数移出的最低位成为新的CF值。

操作数类型和格式:

操作数可以是寄存器或者内存单元,格式为RCR 操作数, 移位次数,移位次数可以是立即数或者CL寄存器。

立即数移位:rcr rcx, 2,将rcx寄存器中的值连同进位标志CF向右循环移动2位。

使用CL寄存器确定移位次数:若CL = 4,rcr [var2], cl,这里var2是一个已定义的内存变量,将其连同进位标志CF向右循环移动CL中指定的4位。

MASM64:移位指令应用场景

一、数学运算

1. 乘法和除法(乘除2的幂次)

逻辑左移(SHL)和算术左移(SAL)用于乘法

左移一位相当于将无符号数或有符号数乘以2。例如,将一个无符号数num存储在rax寄存器中,如果执行shl rax, 1,那么rax中的值就变为原来的2倍。通过左移n位,可以实现乘以2的n次方的快速运算。

逻辑右移(SHR)用于无符号数除法,算术右移(SAR)用于有符号数除法

右移一位相当于将无符号数除以2(舍弃余数)。例如,对于一个无符号数num在eax中,执行shr eax, 1,eax中的值变为原来的一半。对于有符号数,使用SAR指令可以在保持符号不变的情况下进行除法运算,右移n位相当于除以2的n次方。

二、位操作

1. 提取特定的位

可以通过移位操作将需要的位移动到最低位(或最高位),然后再结合逻辑与(AND)指令提取该位。例如,要检查一个32位整数eax中的第10位是否为1,可以先将eax右移10位(shr eax, 10),然后再与1进行逻辑与操作(and eax, 1),如果结果为1,则原数的第10位为1,否则为0。

2. 设置或清除特定的位

假设要设置一个64位整数rax的第5位为1。可以先创建一个只有第5位为1的掩码(通过左移操作,如mov rbx, 1; shl rbx, 5),然后使用逻辑或(OR)指令将这个掩码与rax进行或操作(or rax, rbx)。如果要清除第5位,可以创建一个除了第5位为0其余位为1的掩码(通过先创建全1的数,再左移并取反,如mov rcx, - 1; shl rcx, 5; not rcx),然后与rax进行逻辑与操作(and rax, rcx)。

三、数据压缩与解压缩

1. 数据压缩

在处理一些数据时,如果某些位表示特定的标志或者状态,而这些位在存储或传输时不需要单独的字节或字来表示,可以通过移位操作将这些位组合到一个字节或字中,以节省存储空间或传输带宽。例如,有8个1 - bit的标志位,分别表示不同的状态,可以将它们组合到一个字节中,每个标志位对应字节中的一位。

2. 数据解压缩

与数据压缩相反,当接收到经过压缩的数据时,需要通过移位操作将各个位分解出来,恢复到原始的数据结构中。例如,从一个字节中解压缩出8个1 - bit的标志位,根据位的位置将它们分别存储到不同的变量或寄存器中。

四、加密算法

1. 位混淆与扩散

在一些加密算法(如对称加密算法中的部分操作)中,移位指令用于对数据进行位的混淆和扩散。通过将数据的位进行各种移位操作,可以改变数据的位模式,增加数据的随机性和保密性。例如,在某些简单的加密轮函数中,对数据块中的位进行循环左移或右移操作,然后再与密钥进行异或(XOR)操作等。

64位汇编语言基础