当前位置: 首页 > news >正文

位运算 和 逻辑运算 以及 位运算指令

文章目录

    • ​**​1. 位运算(Bitwise Operations)​**​
      • ​**​(1)按位与(Bitwise AND)`&`​**​
      • ​**​(2)按位或(Bitwise OR)`|`​**​
      • ​**​(3)按位非(Bitwise NOT)`~`​**​
      • ​**​(4)按位异或(Bitwise XOR)`^`​**​
    • ​**​2. 逻辑运算(Logical Operations)​**​
      • ​**​(1)逻辑与(Logical AND)`&&`​**​
      • ​**​(2)逻辑或(Logical OR)`||`​**​
      • ​**​(3)逻辑非(Logical NOT)`!`​**​
    • ​**​3. 常见应用场景​**​
    • ​**​4. 完整示例​**​
    • ​**​总结​**​
      • ​**​为什么 `AND`操作会清零数据?​**​
      • ​**​1. `AND`指令的执行过程​**​
      • ​**​2. 汇编指令的“目标操作数”和“源操作数”​**​
      • ​**​3. 为什么 `XOR reg, reg`比 `AND reg, 0`更高效?​**​
      • ​**​4. 示例:不同清零方式的机器码对比​**​
      • ​**​5. 特殊情况:`SUB reg, reg`也能清零​**​
      • ​**​总结​**​

在 C 语言中,​​与(AND)、或(OR)、非(NOT)、异或(XOR)​​ 是基本的​​位运算​​和​​逻辑运算​​,它们既可以对​​整数进行逐位运算​​,也可以用于​​布尔条件判断​​。


​1. 位运算(Bitwise Operations)​

位运算直接对整数的二进制位进行操作,适用于​​掩码(mask)、标志位、加密算法​​等场景。

​(1)按位与(Bitwise AND)&

​规则​​:两位同时为 1,结果才为 1,否则为 0

​用途​​:​​屏蔽某些位(清零)、检查特定位是否设置​​。

​示例​​:

#include <stdio.h>int main() {unsigned int a = 0b1100; // 12 (二进制 1100)unsigned int b = 0b1010; // 10 (二进制 1010)unsigned int result = a & b;printf("a & b = %u (二进制: %04b)\n", result, result);return 0;
}

​输出​​:

a & b = 8 (二进制: 1000)

​解释​​:

1100 (12)
& 1010 (10)
-----------1000 (8)

​(2)按位或(Bitwise OR)|

​规则​​:两位只要有一个 1,结果就是 1,否则为 0

​用途​​:​​设置某些位为 1​​。

​示例​​:

#include <stdio.h>int main() {unsigned int a = 0b1100; // 12unsigned int b = 0b1010; // 10unsigned int result = a | b;printf("a | b = %u (二进制: %04b)\n", result, result);return 0;
}

​输出​​:

a | b = 14 (二进制: 1110)

​解释​​:

1100 (12)
| 1010 (10)
-----------1110 (14)

​(3)按位非(Bitwise NOT)~

​规则​​:每一位取反(0110)。

​用途​​:​​反转所有位​​。

​示例​​:

#include <stdio.h>int main() {unsigned int a = 0b1100; // 12unsigned int result = ~a;printf("~a = %u (二进制: %08b)\n", result, result);return 0;
}

​输出​​(假设 unsigned int是 8 位):

~a = 243 (二进制: 11110011)

​解释​​:

~ 00001100 (12)
-----------11110011 (243)

​(4)按位异或(Bitwise XOR)^

​规则​​:两位不同时结果为 1,相同时为 0

​用途​​:​​交换变量、加密、校验​​。

​示例​​:

#include <stdio.h>int main() {unsigned int a = 0b1100; // 12unsigned int b = 0b1010; // 10unsigned int result = a ^ b;printf("a ^ b = %u (二进制: %04b)\n", result, result);return 0;
}

​输出​​:

a ^ b = 6 (二进制: 0110)

​解释​​:

1100 (12)
^ 1010 (10)
-----------0110 (6)

​2. 逻辑运算(Logical Operations)​

逻辑运算用于​​条件判断​​,返回 1true)或 0false)。

​(1)逻辑与(Logical AND)&&

​规则​​:所有条件为真(非零)时,结果才为 1,否则为 0

​示例​​:

#include <stdio.h>int main() {int a = 5;int b = 0;int result = (a > 0) && (b > 0);printf("(a > 0) && (b > 0) = %d\n", result);return 0;
}

​输出​​:

(a > 0) && (b > 0) = 0

​(2)逻辑或(Logical OR)||

​规则​​:只要有一个条件为真(非零),结果就是 1,否则为 0

​示例​​:

#include <stdio.h>int main() {int a = 5;int b = 0;int result = (a > 0) || (b > 0);printf("(a > 0) || (b > 0) = %d\n", result);return 0;
}

​输出​​:

(a > 0) || (b > 0) = 1

​(3)逻辑非(Logical NOT)!

​规则​​:如果条件为假(0),结果为 1;否则为 0

​示例​​:

#include <stdio.h>int main() {int a = 5;int result = !a;printf("!a = %d\n", result);return 0;
}

​输出​​:

!a = 0

​3. 常见应用场景​

运算示例用途
&flags & MASK检查标志位是否设置
​**​``​**​`flags
~~MASK反转掩码
^a ^= b; b ^= a; a ^= b;交换两个变量(无临时变量)
&&if (x > 0 && y > 0)逻辑条件判断
​**​``​**​
!if (!error)检查条件是否为假

​4. 完整示例​

#include <stdio.h>int main() {// 位运算unsigned int a = 0b1100; // 12unsigned int b = 0b1010; // 10printf("a & b = %u\n", a & b); // 8printf("a | b = %u\n", a | b); // 14printf("~a = %u\n", ~a);       // 4294967283(32 位取反)printf("a ^ b = %u\n", a ^ b); // 6// 逻辑运算int x = 5, y = 0;printf("x && y = %d\n", x && y); // 0printf("x || y = %d\n", x || y); // 1printf("!x = %d\n", !x);         // 0printf("!y = %d\n", !y);         // 1return 0;
}

​总结​

运算符号类型用途
​与​&位运算屏蔽位、检查标志位
​或​``位运算
​非​~位运算取反所有位
​异或​^位运算交换变量、加密
​逻辑与​&&逻辑运算条件判断
​逻辑或​``
​逻辑非​!逻辑运算取反布尔值

希望这个示例能帮助你理解 C 语言中的​​与、或、非、异或​​运算! 🚀

​为什么 AND操作会清零数据?​

是的,​AND操作会清零数据,是因为运算结果会写回(赋值给)目标操作数​​。在汇编语言中,大多数算术和逻辑运算(如 ADDSUBANDORXOR)都是 ​​“破坏性”​​ 的,即:

  • ​运算结果会覆盖目标操作数​​(通常是第一个操作数)。

  • ​源操作数(第二个操作数)保持不变​​。


​1. AND指令的执行过程​

AND eax, 0为例:

  1. ​CPU 读取 eax的当前值​​(假设是 0x1234)。

  2. ​CPU 读取立即数 0​(二进制 0000 0000)。

  3. ​CPU 对 eax0进行逐位 AND运算​​:

    • 0 AND X = 0(任何数与 0进行 AND,结果都是 0)。

    • 因此,eax的每一位都会变成 0

  4. ​运算结果写回 eax​,所以 eax最终为 0


​2. 汇编指令的“目标操作数”和“源操作数”​

在汇编语言中,​​大多数指令的格式是 OP 目标, 源​:

  • ​目标操作数​​(第一个操作数):​​会被修改​​,存放运算结果。

  • ​源操作数​​(第二个操作数):​​不会被修改​​,仅用于计算。

例如:

AND eax, 0   ; eax = eax & 0(eax 被修改,0 不变)
ADD ebx, ecx ; ebx = ebx + ecx(ebx 被修改,ecx 不变)
XOR edx, edx ; edx = edx ^ edx(edx 被修改)

​3. 为什么 XOR reg, regAND reg, 0更高效?​

虽然 AND reg, 0也能清零寄存器,但 ​XOR reg, reg是更推荐的方式​​,原因:

方法指令长度CPU 优化适用场景
AND reg, 0需要编码 0(可能占用更多字节)一般需要清零时
XOR reg, reg更短(只需操作寄存器)高度优化(CPU 知道它是清零操作)推荐方式
MOV reg, 0需要编码 0(可能较长)一般直接赋值

XOR reg, reg的优势:​

  • ​指令更短​​(不需要额外存储 0)。

  • ​CPU 特殊优化​​(某些 CPU 会识别 XOR reg, reg并直接清零,而不真正执行异或运算)。

  • ​通用性强​​(适用于所有 x86/x64 CPU)。


​4. 示例:不同清零方式的机器码对比​

我们对比 ANDXORMOV的机器码(x86-64):

指令机器码(字节)说明
AND eax, 083 E0 003 字节(83 E0+ 00
XOR eax, eax31 C02 字节(更短)
MOV eax, 0B8 00 00 00 005 字节(B8+ 4 字节 0

显然,​XOR eax, eax是最短、最高效的方式​​。


​5. 特殊情况:SUB reg, reg也能清零​

除了 ANDXOR,​SUB reg, reg也能清零寄存器​​:

SUB eax, eax ; eax = eax - eax = 0

它的机器码是 29 C0(2 字节),和 XOR一样高效。


​总结​

问题答案
​为什么 AND reg, 0会清零?​因为 AND运算结果会写回目标操作数(第一个操作数)。
​为什么 XOR reg, regAND reg, 0更好?​XOR指令更短,CPU 优化更好。
​其他清零方式?​SUB reg, regMOV reg, 0(但 XOR最优)。
​所有逻辑/算术运算都会修改目标操作数吗?​是的(如 ADDORSUBXOR都会修改目标操作数)。

如果你在写汇编代码,​​优先使用 XOR reg, reg来清零寄存器​​!

http://www.dtcms.com/a/469586.html

相关文章:

  • 工地招聘网站广告设计与制作视频
  • C++右值语义解析
  • java-高级技术(单元测试、反射)
  • 厦门做网站公司有哪些邯郸
  • Spring Boot 项目集成 Gradle:构建、测试、打包全流程教程
  • 电商主要是做什么工作东莞seo收费
  • SAP MM 通用物料移动过账冲销接口分享
  • 设计logo免费网站电商网站对比表格
  • SAP Vendor Invoice Management by OpenText (VIM)
  • 用 PyQt5 + PyPDF2 做一个“智能分页”的大 PDF 拆分器(含 GUI 与命令行双版本,附完整源码)
  • 芯片结构简介-arm/x86
  • Agentic AI 教程与 AI 编程入门:从基础到实战(含代码、流程图与 Prompt)
  • 做一个公司网站一般多少钱自己做的网站怎么放视频
  • 开源软件License科普:GPL/LGPL/Apache/木兰等license解析
  • React闭包陷阱(stale closure)介绍(React状态更新引用旧值)解决方法:使用函数式更新写法
  • 【Java数据结构】Map 与 Set 接口全解析
  • 海洋做网站大连网上办事大厅
  • 创新平台网站建设方案wordpress 恶意代码
  • Jupyter Notebook/Lab的高级技巧与快捷键
  • Request 和 Response 都使用了 Fetch API 的 Body 混入
  • 大数据毕业设计选题推荐-基于大数据的人体体能活动能量消耗数据分析与可视化系统-大数据-Spark-Hadoop-Bigdata
  • 电子电气架构 --- 操作系统的发展趋势
  • R语言绘图神器| ggplot2与其基本用法介绍
  • 自动负氧离子监测站:科技赋能,精准守护清新空气
  • 商务卫士包括网站建设seo优化谷歌
  • java-代码随想录第66天|Floyd 算法、A * 算法精讲 (A star算法)
  • 外贸展示网站多少钱企业画册内容
  • 上门做网站哪里有wordpress调用网页
  • 【部署python网站】宝塔面板 小目标2:实时搜索网上资源文件网站放在服务器上 用AI做一个作品,不断迭代。
  • ubuntu服务器重启,xinference自动加载模型脚本