汇编指令-NOT、SHL、LSR
取反NOT
在汇编语言中,NOT
是一个按位逻辑非操作指令。它对一个操作数中的每一位执行逻辑取反操作,即将0变成1,将1变成0。
例如,在某些CPU架构(如x86)的汇编语言中,对于一个字节或字(以及其他大小的寄存器或内存位置),NOT
指令可以这样使用:
not al ; 对AL寄存器进行取反操作
not eax ; 对EAX寄存器进行取反操作
not [ebx] ; 对EBX寄存器指向的内存地址处的数据进行取反操作
对于给定的操作数 AL = 1011000
执行 NOT
操作后,结果确实会是 0100111
,因为每一位都被翻转了。
请注意,不同的CPU架构可能有不同的指令来实现按位取反操作,并且指令的语法也有所不同。但在大多数情况下,汇编程序员通过查阅相应架构的指令集手册来正确编写和使用这些指令。
左移指令SHL
在汇编语言中,SHL
是一个逻辑左移(Shift Left Logical)指令。该指令用于将操作数中的位向左移动指定的位数,同时遵循以下规则:
-
移动位数:
- 在x86架构下,可以使用立即数或CL寄存器来指定移动的位数。
- 如果是
SHL dest, imm8
形式,则dest操作数向左移动imm8指定的位数。 - 如果是
SHL dest, CL
形式,则dest操作数向左移动CL寄存器中的值那么多位。
-
数据移位:
- 操作数的高位被移出并写入进位标志(CF)中。
- 最低位则用0填充。
-
影响的标志位:
- 移位操作会改变若干状态标志,包括:
- CF(进位标志):移出的最高位被存入CF中。
- OF(溢出标志):如果进行的是算术移位(对于无符号整数而言,SHL和逻辑移位效果相同),当移位前的最高有效位(MSB)与移位后次高位不相同时,OF设置为1,否则为0;对于逻辑移位,SHL不会产生OF=1的情况,除非移位次数不是1,此时OF的值不确定。
- SF(符号标志):根据移位后的最高位更新,反映了移位后结果的正负性。
- ZF(零标志):如果移位后结果为0,则ZF置1,否则置0。
- PF(奇偶标志):按照移位后结果的最低8位中1的个数为偶数还是奇数来设置。
- 移位操作会改变若干状态标志,包括:
示例代码片段:
; 例如,假设AL寄存器中存储了二进制数 01001000b
mov al, 01001000b ; 将这个值加载到AL中
shl al, 1 ; 将AL的内容左移一位
; 执行后,AL的值变为 10010000b (原来的次高位成了最高位,最低位补0)
通过逻辑左移操作,可以实现乘以2的幂次运算(因为每左移一位相当于数值翻倍)。同时,它也可以用来快速清零某个寄存器的部分或全部位,或者在处理循环计数、位掩码等场合发挥重要作用。
右移指令LSR
在汇编语言中,右移指令通常用于逻辑右移(Logical Shift Right, LSR)和算术右移(Arithmetic Shift Right, SAR)。这两种操作都会将操作数的位向右移动指定的数量。
-
LSR (Shift Right Logical)
- 在x86架构中,对应指令是
SHR
。 - 示例:
SHR dest, imm8
或SHR dest, CL
。 - 该指令将dest操作数中的位向右移动指定的位数,并且用0填充空出的最高位。
- 移出的最低位会被写入进位标志(CF)中。
- 在x86架构中,对应指令是
-
SAR (Shift Right Arithmetic)
- 在x86架构中,对应指令是
SAR
。 - 示例:
SAR dest, imm8
或SAR dest, CL
。 - 算术右移与逻辑右移类似,但保持了原操作数的符号位不变。即对于有符号整数,即使在移位后,最高位仍保留原来的值(正数则为0,负数则为1),这样确保移位后的数值保持相同的符号。
- 移出的最低位同样会被写入进位标志(CF)中。
- 在x86架构中,对应指令是
例如:
; 假设AL寄存器中存储了二进制补码表示的有符号数 10000001b (-1)
mov al, 10000001b
sar al, 1 ; 对AL进行算术右移一位
; 执行后,AL的值变为 11000000b (-1除以2的结果,符号位不变)
shr al, 1 ; 对AL进行逻辑右移一位
; 执行后,AL的值变为 01000000b (无符号数右移结果)
通过右移操作,可以实现除以2的幂次运算(因为每右移一位相当于数值除以2)。同时,在处理循环计数、数据压缩、乘法或除法预计算等场景下也非常有用。