目录
[与 (&):](#与 (&):)
[或 (|):](#或 (|):)
[异或 (^):](#异或 (^):)
[取反 (~):](#取反 (~):)
[左移 (<<):](#左移 (<<):)
[右移 (>>):](#右移 (>>):)

一、位运算概述
位运算是计算机底层操作的核心,直接操作数据的二进制位。计算机硬件通过逻辑门(如与、或、非、异或)实现位运算,效率极高,广泛应用于嵌入式系统、加密算法、图形处理和算法优化。
计算机本质上通过加法器电路执行加法,其他算术运算(如减法、乘法、除法)可通过位运算和加法组合实现。
位运算是对整数的二进制表示逐位操作,以下是核心位运算及其规则。
二、基本位运算符
| 运算符 | 名称 | 规则说明 | 示例 (以 4 和 5 为例) | 结果 |
|---|---|---|---|---|
| & | 与 | 同位均为1时结果为1,否则为0 | 00000100 & 00000101 | 00000100 (4) |
| 或 | 同位有一个1时结果为1,否则为0 | 00000100 | 00000101 | 00000101 (5) | |
| ^ | 异或 | 同位不同时结果为1,相同为0 | 00000100 ^ 00000101 | 00000001 (1) |
| ~ | 取反 | 0变1,1变0 | ~00000100 | 11111011 (-5,补码) |
| << | 左移 | 向左移位,低位补0 | 00000100 << 1 | 00001000 (8) |
| >> | 右移 | 向右移位,高位补符号位 | 00000100 >> 1 | 00000010 (2) |
汇编实现爱过程
与 (&):
仅当两个操作数的对应位均为1时,结果位为1;否则为0。 C示例:4 & 5 → 4 汇编指令:AND
mov eax, 4 ; 00000100
and eax, 5 ; 00000100 & 00000101 = 00000100
; eax结果为4
或 (|):
只要两个操作数的对应位中有一个为1,结果位为1;否则为0。 C示例:4 | 5 → 5 汇编指令:OR
mov eax, 4
or eax, 5 ; 00000100 | 00000101 = 00000101
; eax结果为5
异或 (^):
当两个操作数的对应位不同时,结果位为1;相同则为0。 C示例:4 ^ 5 → 1 汇编指令:XOR
mov eax, 4
xor eax, 5 ; 00000100 ^ 00000101 = 00000001
; eax结果为1
取反 (~):
将操作数的每位翻转(0变1,1变0)。 C示例:~4 → -5(补码) 汇编指令:NOT
mov eax, 4
not eax ; ~00000100 = 11111011(补码为-5)
mov eax, 4 not eax ; ~00000100 = 11111011(补码为-5)
左移 (<<):
将操作数的位向左移动,低位补0。 C示例:4 << 1 → 8 汇编指令:SHL(逻辑左移)
mov eax, 4
shl eax, 1 ; 00000100 << 1 = 00001000,结果为8
右移 (>>):
将操作数的位向右移动,符号位填充高位(有符号整数)。 C示例:4 >> 1 → 2 汇编指令:SAR(算术右移,保留符号位)或 SHR(逻辑右移)
mov eax, 4
sar eax, 1 ; 00000100 >> 1 = 00000010,结果为2
记忆技巧(口诀与联想)
- 与 (&):同位"都1才1",否则0。联想:像"严格的考试",只有双方都满足条件(1)才通过。
- 或 (|):有1就行,轻松过关。联想:像"宽松的规则",只要有一方满足条件(1)就行。
- 异或 (^):不同为1,相同为0。联想:像"互斥的开关",差异才触发。
- 取反 (~):翻转黑白,0变1,1变0。联想:像"反转照片底片"。
- 左移 (<<):向左挤,低位补0,相当于乘2。联想:像"数字向左跑,后面补0"。
- 右移 (>>):向右挤,高位补符号位,相当于除2。联想:像"数字向右滑,前面补符号"。
技术原理
位运算是计算机硬件的基本操作,通过逻辑门电路实现:
- 硬件层面:与、或、异或等操作由逻辑门直接执行,加法通过全加器电路实现。
- 补码表示:计算机使用补码表示负数,~x + 1 计算负数,简化减法实现。
- 移位操作:左移和右移通过移位寄存器实现,优化乘法和除法。
- 应用场景:位运算在优化算法(如快速乘法、位图)、加密(如AES)、硬件驱动和压缩算法中有广泛应用。
技术栈解释
- 编程语言:C语言(高效,接近硬件,广泛支持位运算)。
- 硬件支持:CPU的ALU(算术逻辑单元)直接执行位运算,速度快。
- 限制:需注意整数溢出(如左移导致符号位变化)、符号位处理(右移)和32/64位系统差异。
- 优化:位运算避免浮点运算,减少指令周期,适合嵌入式和高性能计算。
使用位运算实现基本算术运算
加法实现
原理:加法通过异或(无进位和)与与运算(进位)迭代完成。
汇编核心思路(使用 AND / XOR / SHL):
add_bit:
mov ecx, ebx ; 保存b
xor eax, ebx ; sum = a ^ b
and ecx, ebx ; carry_temp = a & b
shl ecx, 1 ; carry = carry_temp << 1
mov ebx, ecx ; b = carry
test ebx, ebx
jnz add_bit ; 如果还有进位,继续循环
ret
C
int add(int a, int b) {
while (b != 0) {
int sum = a ^ b;
int carry = (a & b) << 1;
a = sum;
b = carry;
}
return a;
}
减法实现
原理:a - b = a + (-b),负数用补码 ~b + 1 表示。
subtract_bit:
not ebx ; ~b
add ebx, 1 ; +1 得到 -b
jmp add_bit ; 调用加法逻辑
C源代码:
C
int subtract(int a, int b) {
b = ~b + 1;
return add(a, b);
}
乘法实现
原理:类似手动乘法,对乘数每一位为1的位置,被乘数左移后累加。
汇编核心思路(使用 TEST / SHL / SHR):
multiply_bit:
xor ecx, ecx ; result = 0
mul_loop:
test ebx, 1 ; if (b & 1)
jz skip_add
add ecx, eax ; result += a
skip_add:
shl eax, 1 ; a <<= 1
shr ebx, 1 ; b >>= 1
test ebx, ebx
jnz mul_loop
mov eax, ecx
ret
C
int multiply(int a, int b) {
int result = 0;
while (b != 0) {
if (b & 1) {
result = add(result, a);
}
a = a << 1;
b = b >> 1;
}
return result;
}
除法实现
原理:类似长除法,通过反复左移除数找到最大倍数,再逐步减去并设置商的对应位。
C
int divide(int a, int b) {
if (b == 0) return 0;
int quotient = 0;
int temp = b;
int shift = 0;
while (temp <= a && temp > 0) {
temp = temp << 1;
shift++;
}
temp = temp >> 1;
shift--;
while (shift >= 0) {
if (temp <= a) {
a = subtract(a, temp);
quotient |= (1 << shift);
}
temp = temp >> 1;
shift--;
}
return quotient;
}
七、完整源代码
C
#include <stdio.h>
// 加法、减法、乘法、除法函数(同上)
int main() {
int a = 15, b = 3;
printf("加法: %d + %d = %d\n", a, b, add(a, b));
printf("减法: %d - %d = %d\n", a, b, subtract(a, b));
printf("乘法: %d * %d = %d\n", a, b, multiply(a, b));
printf("除法: %d / %d = %d\n", a, b, divide(a, b));
return 0;
}