【新书推荐】5.2 位运算符

news2024/9/23 3:17:53

本节必须掌握的知识点:

   位运算

   示例十七

   代码分析

   汇编解析

5.2.1 位运算

位运算符如表5-2所示:

运算符

作用

示例

&

按位与

两个操作数同时为1,结果为1;

|

按位或

两个操作数只要有一个为1,结果就为1;

~

按位非

操作数为1,结果为0;操作数为0,结果就为1;

^

按位异或

两个操作数相同,结果为0;不相同结果为1;

<<

左移

右侧空位补0

>>

右移

左侧空位补符号位

>>

无符号右移

左侧空位补0

                              表5-2位运算符

所有的位运算只适用于char、short、int、unsigned char、unsigned short、unsigned int整型数据类型。位运算需要按位表示,例如:unsigned char c = 07h。

把变量c按位表示:【最左侧为最高位第7位,最右侧为最低位第0位】。

0

0

0

0

0

1

1

1

       ■&按位与运算

       语法格式:expr1 & expr2;两个操作数同时为1,结果为1。

  • | 按位或运算

语法格式:expr 1 | expr2;两个操作数只要有一个为1,结果就为1。

~按位非运算

语法格式:~expr 1;操作数为1,结果为0;操作数为0,结果就为1。

^按位异或运算

语法格式:expr 1 ^ expr 2 ;两个操作数相同,结果为0;不相同结果为1;

<<左移运算

0x01<<1左移表示,所有的位向左移一位,右侧补0

0

0

0

0

0

0

0

1

 向左移一位

0

0

0

0

0

0

1

0

0xEF<<3左移表示,所有的位向左移三位,右侧补0

1

1

1

0

1

1

1

1

向左移三位

0

1

1

1

1

0

0

0

>>右移运算

0x01>>1右移表示,所有的位向左移一位,左侧补0

0

0

0

0

0

0

0

1

向右移一位

0

0

0

0

0

0

0

0

有符号数0xEF>>3右移表示,所有的位向左移一位,有符号左侧补符号位。

1

1

1

0

1

1

1

1

向右移三位

1

1

1

1

1

1

0

1

5.2.2 示例十七

/*

   位运算符

*/

#include <stdio.h>

#include <stdlib.h>

int main(void) {

    char c1 = 0x01;//十六进制数

    char c2 = 0xEF;

    printf("%d\n", c1 & c2);//与运算

    printf("%d\n", c1 | c2);//或运算

    printf("%d\n", ~c1);    //非运算

    printf("%d\n", c1 ^ c2);//异或运算

    printf("%d\n", c1 << 1);//左移

    printf("%d\n", c2 >> 3);//右移

    system("pause");

    return 0;

}

●输出结果:

1

-17

-2

-18

2

-3

5.2.3 代码分析

示例代码非常简单,分别输出两个char类型变量c1和c2与运算、或运算、非运算、异或运算、左移和右移的结果。

5.2.4 汇编解析

汇编代码

;C标准库头文件和导入库

include vcIO.inc

.data 

c1      sbyte    1           

c2      sbyte    0EFh

.const

szMsg db "%d",0dh,0ah,0

.code

start:

         movsx eax,sbyte ptr c1

         movsx ebx,sbyte ptr c2     

         and eax,ebx

         invoke printf,offset szMsg,eax;输出结果

         ;

         movsx eax,sbyte ptr c1

         movsx ebx,sbyte ptr c2     

         or eax,ebx

         invoke printf,offset szMsg,eax;输出结果

         ;

         movsx eax,sbyte ptr c1

         not eax

         invoke printf,offset szMsg,eax;输出结果

         ;

         movsx eax,sbyte ptr c1

         movsx ebx,sbyte ptr c2     

         xor eax,ebx

         invoke printf,offset szMsg,eax;输出结果 

         ;

         movsx eax,sbyte ptr c1

         shl eax,1

         invoke printf,offset szMsg,eax;输出结果 

         ;

         movsx eax,sbyte ptr c2

         sar eax,3

         invoke printf,offset szMsg,eax;输出结果 

         ;    

         invoke _getch     

         ret                     

end start

输出结果:

1

-17

-2

-18

2

-3

       上述汇编代码需要关注以下几点:

       变量c1和c2的数据类型为sbyte 8位有符号整型。因为printf函数的参数入栈为32位,因此需要使用movsx指令将变量c1和c2的符号位扩展为32位,然后再进行位运算。汇编指令and与运算,or或运算,not非运算,xor异或运算。

       接下来的移位指令shl为左移指令,将eax的所有数据位左移1位。sar右移指令为有符号数右移指令,将eax的所有数据位右移3位,左侧最高位填充符号位。

【注意】masm32汇编器不支持0x作为前缀的十六进制数格式,改用后缀h表示十六进制数。

反汇编代码

    char c1 = 0x01;//十六进制数

00FA1838  mov         byte ptr [c1],1 

    char c2 = 0xEF;

00FA183C  mov         byte ptr [c2],0EFh 

    printf("%d\n", c1 & c2);//与运算

00FA1840  movsx       eax,byte ptr [c1] 

00FA1844  movsx       ecx,byte ptr [c2] 

00FA1848  and         eax,ecx 

00FA184A  push        eax 

00FA184B  push        offset string "%d\n" (0FA7B30h) 

00FA1850  call        _printf (0FA104Bh) 

00FA1855  add         esp,8 

    printf("%d\n", c1 | c2);//或运算

00FA1858  movsx       eax,byte ptr [c1] 

00FA185C  movsx       ecx,byte ptr [c2] 

00FA1860  or          eax,ecx 

00FA1862  push        eax 

00FA1863  push        offset string "%d\n" (0FA7B30h) 

00FA1868  call        _printf (0FA104Bh) 

00FA186D  add         esp,8 

    printf("%d\n", ~c1); //非运算

00FA1870  movsx       eax,byte ptr [c1] 

00FA1874  not         eax 

00FA1876  push        eax 

00FA1877  push        offset string "%d\n" (0FA7B30h) 

00FA187C  call        _printf (0FA104Bh) 

00FA1881  add         esp,8 

    printf("%d\n", c1 ^ c2);//异或运算

00FA1884  movsx       eax,byte ptr [c1] 

00FA1888  movsx       ecx,byte ptr [c2] 

00FA188C  xor         eax,ecx 

00FA188E  push        eax 

00FA188F  push        offset string "%d\n" (0FA7B30h) 

00FA1894  call        _printf (0FA104Bh) 

00FA1899  add         esp,8 

    printf("%d\n", c1 << 1);//左移

00FA189C  movsx       eax,byte ptr [c1] 

    printf("%d\n", c1 << 1);//左移

00FA18A0  shl         eax,1 

00FA18A2  push        eax 

00FA18A3  push        offset string "%d\n" (0FA7B30h) 

00FA18A8  call        _printf (0FA104Bh) 

00FA18AD  add         esp,8 

    printf("%d\n", c2 >> 3);//右移

00FA18B0  movsx       eax,byte ptr [c2] 

00FA18B4  sar         eax,3 

00FA18B7  push        eax 

00FA18B8  push        offset string "%d\n" (0FA7B30h) 

00FA18BD  call        _printf (0FA104Bh) 

00FA18C2  add         esp,8 

上述反汇编代码中调用printf函数使用push/call指令,movsx语句中使用byte ptr指定数据类型,其余反汇编代码与汇编代码相同,不再赘述。

练习

1、

int a = -1;

int b = a > 3;

求变量b最后的值

int c = 0;

int d = !c;

求变量d最后的值

2、请写出下出对应的C语言代码。

00401010   push        ebp

00401011   mov         ebp,esp

00401013   sub         esp,48h

00401016   push        ebx

00401017   push        esi

00401018   push        edi

00401019   lea         edi,[ebp-48h]

0040101C   mov         ecx,12h

00401021   mov         eax,0CCCCCCCCh

00401026   rep stos    dword ptr [edi]

00401028   mov         dword ptr [ebp-4],0

0040102F   xor         eax,eax

00401031   cmp         dword ptr [ebp-4],0

00401035   sete        al

00401038   mov         ecx,dword ptr [ebp-4]

0040103B   add         ecx,eax

0040103D   mov         dword ptr [ebp-8],ecx

00401040   push        offset string "pause" (0042201c)

00401045   call        system (00401090)

0040104A   add         esp,4

0040104D   xor         eax,eax

3、

int a = 7;

int b = ( a + 4 >4 ?  12 : 13);

本文摘自编程达人系列教材《汇编的角度——C语言》。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1430964.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Apollo配置中心之Server端

一、通知机制 二、架构思考 1、配置变更如何通知客户端&#xff1f; &#xff08;1&#xff09;如何建立长轮询&#xff1f; 2、客户端如何拉取数据&#xff1f; &#xff08;1&#xff09;如何拉取数据&#xff1f; 3、如何发现变更数据&#xff1f; &#xff08;1&…

全国医院及文体设施相关情况数据,shp+excel格式,多字段可查询,所见即所得

基本信息. 数据名称: 全国医院及文体设施相关情况数据 数据格式: shpexcel 数据几何类型: 面 数据坐标系: WGS84 数据来源&#xff1a;网络公开数据 数据字段&#xff1a; 序号字段名称字段说明1province省级名称2city城市名称3city_dm城市代码4tsgcss2020公共图书馆图…

vulhub中 Apache Airflow Celery 消息中间件命令执行漏洞复现(CVE-2020-11981)

Apache Airflow是一款开源的&#xff0c;分布式任务调度框架。在其1.10.10版本及以前&#xff0c;如果攻击者控制了Celery的消息中间件&#xff08;如Redis/RabbitMQ&#xff09;&#xff0c;将可以通过控制消息&#xff0c;在Worker进程中执行任意命令。 1.利用这个漏洞需要控…

[基础IO]文件描述符{重定向/perror/磁盘结构/inode/软硬链接}

文章目录 1. 再识重定向2.浅谈perror()3.初始文件系统4.软硬链接 1. 再识重定向 图解./sf > file.txt 2>&1 1中内容拷贝给2 使得2指向file 再学一个 把file的内容传给cat cat拿到后再给file2 2.浅谈perror() open()接口调用失败返回-1,并且错误码errno被适当的设置,…

Hive 主要内容一览

Hive架构 用户接口&#xff1a;Client CLI&#xff08;command-line interface&#xff09;、JDBC/ODBC(jdbc访问hive) 元数据&#xff1a;Metastore 元数据包括&#xff1a;表名、表所属的数据库&#xff08;默认是default&#xff09;、表的拥有者、列/分区字段、表的类型&am…

CTF(5)

一、[SWPUCTF 2021 新生赛]ez_caesar 1、题目 import base64 def caesar(plaintext):str_list list(plaintext)i 0while i < len(plaintext):if not str_list[i].isalpha():str_list[i] str_list[i]else:a "A" if str_list[i].isupper() else "a"…

vulhub中Adminer远程文件读取漏洞复现(CVE-2021-43008)

Adminer是一个PHP编写的开源数据库管理工具&#xff0c;支持MySQL、MariaDB、PostgreSQL、SQLite、MS SQL、Oracle、Elasticsearch、MongoDB等数据库。 在其版本1.12.0到4.6.2之间存在一处因为MySQL LOAD DATA LOCAL导致的文件读取漏洞。 参考链接&#xff1a; https://gith…

端到端实现高精地图重建(TopoNet解读和横评)

论文出处 [2304.05277] Graph-based Topology Reasoning for Driving Scenes (arxiv.org)https://arxiv.org/abs/2304.05277 TopoNet TopoNet的目标是从车辆上安装的多视角摄像头获取图像&#xff0c;感知实体并推理出驾驶场景的拓扑关系&#xff0c;实现端到端预测&#xf…

2017年苏州大学837复试机试C/C++

2017年苏州大学复试机试 要求 要求用C/C编程&#xff1b;对程序中必要的地方进行注释。上机规则 请在电脑桌面上新建一个文件夹文件夹名为考试姓名&#xff08;中文&#xff09;&#xff1b;考试完毕后&#xff0c;将所编写的文件放在上述文件中。 第一题&#xff08;20分&…

Node.js-1

Node.js 简介 定义&#xff1a;Node.js 是一个跨平台 JavaScript 运行环境&#xff0c;使开发者可以搭建服务器端的 JavaScript 应用程序 为什么 Node.js 能执行 JS 代码&#xff1a; Chrome 浏览器能执行 JS 代码&#xff0c;依靠的是内核中的 V8引擎&#xff08;即&#x…

react 使用react-seamless-scroll实现无缝滚动

文章目录 1. 实现无缝滚动效果2. react-seamless-scroll 无缝滚动案例介绍3. react 项目集成3.1 项目引入 cssSeamlessScroll 滚动组件3.2 完整代码3.2.1 newBet.tsx 代码3.2.2 index.module.scss 1. 实现无缝滚动效果 实现单步向下滚动点击更多展开&#xff0c;收起&#xff0…

[Angular 基础] - Angular 渲染过程 组件的创建

[Angular 基础] - Angular 渲染过程 & 组件的创建 之前的笔记为了推进度写的太笼统了&#xff08;只有功能没有其他&#xff09;&#xff0c;当时学的时候知道是什么东西&#xff0c;但是学完后重新复习发现有些内容就记不清了&#xff0c;所以重新用自己的语言总结一下 …

[晓理紫]每日论文分享(有中文摘要,源码或项目地址)--强化学习、模仿学习、机器人

专属领域论文订阅 关注{晓理紫}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 如果你感觉对你有所帮助&#xff0c;请关注我&#xff0c;每日准时为你推送最新论文。 为了答谢各位网友的支持&#xff0c;从今日起免费为3…

基于YOLOv8算法的照片角度分类项目实践

目录 一、任务概述二、YOLOv8算法简介2.1 算法改进2.2 算法特点2.3 网络结构2.4 性能比较 三、工程实践3.1 安装算法框架库ultralytics3.2 库存照片预处理3.2.1 提取所有图片3.2.2 去除冗余的相同照片3.2.3 去除无车辆照片3.2.4 随机提取指定数量的图片 3.3 照片朝向分类3.3.1 …

项目02《游戏-06-开发》Unity3D

基于 项目02《游戏-05-开发》Unity3D &#xff0c; 接下来做 背包系统的 存储框架 &#xff0c; 首先了解静态数据 与 动态数据&#xff0c;静态代表不变的数据&#xff0c;比如下图武器Icon&#xff0c; 其中&#xff0c;武器的名称&#xff0c;描述&#xff…

宠物空气净化器哪个牌子好?除猫毛好的猫用空气净化器牌子推荐

大家都知道&#xff0c;宠物掉毛的情况有多么严重。特别是在换毛的季节&#xff0c;简直就是毛发遍地飞。这给家里有小孩和老人的人带来了很多困扰&#xff0c;他们可能会流鼻涕、过敏等等。而且&#xff0c;宠物有时候也会随地大小便&#xff0c;那个味道真的很难闻。家里的人…

【揭秘】JMeter JDBC脚本实战,让你的性能测试更高效!

Jmeter使用jdbc的场景&#xff1a; 1、接口功能测试时&#xff0c;需要查询验证码 2、通过数据库查询已经注册的手机号码 3、性能测试时&#xff0c;直接对某个SQL做性能测试&#xff0c;快速的发现性能问题 添加一个jdbc的配置元件 配置jdbc连接信息 配置说明&#xff1a; 1…

如何看待敏捷

局部清晰&#xff0c;循序渐进&#xff0c;整体清晰增量型 考试要么预测&#xff08;传统&#xff0c;瀑布&#xff09;&#xff0c;要么敏捷&#xff0c;要么就用混合方法 项目生命周期两种&#xff1a;预测型、敏捷型 开发生命周期四种&#xff1a;预测型、迭代型、增量型、…

JVM工作原理与实战(三十四):解决GC问题的方法

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、常见的垃圾回收&#xff08;GC&#xff09;模式 二、解决GC问题的方法 1.优化基础JVM参数 2.更换垃圾回收器 3.优化垃圾回收器的参数 总结 前言 JVM作为Java程序的运行环境&a…

龙龙送外卖pta[代码+讲解]

题目 题解 代码 题目 龙龙是“饱了呀”外卖软件的注册骑手&#xff0c;负责送帕特小区的外卖。帕特小区的构造非常特别&#xff0c;都是双向道路且没有构成环 —— 你可以简单地认为小区的路构成了一棵树&#xff0c;根结点是外卖站&#xff0c;树上的结点就是要送餐的地址…