反汇编分析赋值与自增自减

news/2024/9/20 3:54:10/文章来源:https://www.cnblogs.com/DSCL-ing/p/18414576

目录
  • ++(--)
    • 后置的++(--)真的是先使用,后自增吗?
    • 后置++和前置++的差别
  • 复杂表达式
    • ++i+++i+++i
    • 贪心法
    • 编译器的贪心规则不是保证一定正确的规则
  • 赋值的原理

++(--)


后置的++(--)真的是先使用,后自增吗?


概念:前置++是先自增,后使用; 后置++是先使用,后自增.

下面从汇编角度看后置++的原理.如图:

image-20240502103655957

从上图来看,就是正常的先使用,后自增.图中的a++是有使用对象的,先把a的值给b,然后再自增.

但是如果只有单独的a++,并没有接收方呢? 看汇编:

image-20240502105312246

上面汇编说明,后置++是先使用,后自增的说法仅仅是表述方便.对编译器看来后置++先使用这一步骤,取决于有没有使用者.


后置++和前置++的差别

再看后置++与前置++:

image-20240502110116893

可以看到,如果在没有接收方的情况下, C语言的前置++和后置++是没有差别的.所以,习惯哪个就用哪个.

(在C++中,从++运算符重载的实现上看.后置++确实可能会慢一些)


复杂表达式


++i+++i+++i

分别使用vs和gcc计算++i+++i+++i的结果,如图:

image-20240502163539456

可以发现不同平台下这样的表达式结果可能是不一样的.为什么? 看看汇编下的它们长什么样:

image-20240502170103052

(tips:++i不加括号计算的结果也是一样的)

可以发现,两平台下的汇编代码的逻辑是有差别的,说明这种复杂表达式在不同平台的计算路径是不一样的,是因为编译器识别表达式的方式不一致/不确定导致的,可能是同时加载至寄存器,也可能是分批加载.最终导致应用层的表现不一致.

因此,类似这种复杂表达式,做不到统一规范的.我们一律不推荐使用.

还有一个问题,那就是编译器如何对这种复杂表达式完成变量与符号的识别和匹配的呢? 引入贪心规则,见下文.


贪心法

贪心法

C 语言有这样一个规则:每一个符号应该包含尽可能多的字符。也就是说,编译器将程序分解成符号的方法是,从左到右一个一个字符地读入,如果该字符可能组成一个符号,那么再读入下一个字符,判断已经读入的两个字符组成的字符串是否可能是一个符号的组成部分;如果可能,继续读入下一个字符,重复上述判断,直到读入的字符组成的字符串已不再可能组成一个有意义的符号。这个处理的策略被称为“贪心法”。需要注意的是,除了字符串与字符常量,符号的中间不能嵌有空白(空格、制表符、换行符等)。比如:==是单个符号,而= =是两个等号。解释:读到空格后,就需要判断是否是完整的操作符,一个=号能够独立,不需要再贪心组合;if和()中间可以有空格,如果读到的是if,就算读到空格,也不能算是独立的结构,还需要继续读下去,直到遇到()。

按照这个规则可能很轻松的判断 a+++b 表达式与 a++ +b 一致。
那++i+++i+++i;会被解析成什么样子呢?希望读者好好研究研究。另外还可以考虑一下这个表达式的意思:a+++++b;


编译器的贪心规则不是保证一定正确的规则

观察i+++++j的情况,如果使用编译器的自动对齐功能,对齐后的表达式是告警的

image-20240502173608784

如果我们手动调整,则没有告警

image-20240502173759840

这说明,编译器的贪心匹配规则只是尽可能去匹配,解释表达式,解释的结果不一定是对的.所以,读者们以后也要注意,不要绝对相信编译器的告警.编译器的告警也有可能会出错的.

另外,从这句代码中可以发现,C语言的空格并不是只让代码变得好看一些,还有起到操作符匹配划分的作用.

查看linux反汇编:

gcc -g test.c //生成debug版本可执行文件,便于查看源码位置,如果不带-g选项则不显示源码

linux反汇编命令:objdump -S a.out > a.s //S == source


赋值的原理

赋值是将赋值符号右边变量的值取出放到寄存器中,然后再通过寄存器赋值给赋值符号左边的变量.

image-20240526214709872

因此"右值"有常性,是因为右值被放到了寄存器中,寄存器有常性,右值就有常性.

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

26. 多进程理论、操作

1. 多进程相关理论 1.1 什么是进程 进程是一个正在执行的任务或程序 负责执行任务的是CPU (1)单任务 单核CPU+多道技术  实现多个进程的伪并发 (2)多任务 多个任务并发执行 1.2 进程和程序的区别 程序是代码的集合体 进程是程序的执行过程 1.3 进程的调度算法 (1)先来…

网络基础--UPnP基本原理

网络基础--UPnP基本原理 1、简介 UPnP是通用即插即用(Universal Plug and Play)的缩写,主要用于设备的智能互联互通,使用UPnP协议不需要设备驱动程序,它可以运行在目前几乎所有的操作系统平台上,使得在办公室、家庭和其他公共场所方便地构建设备互联互通成为可能。UPNP为…

VastbaseG100集群部署实操

背景 近日的工作涉及到数据库的集群部署,为了熟悉过程,参考VastgbaseG100官方文档进行部署。 参考文档 https://docs.vastdata.com.cn/zh/docs/VastbaseG100Ver2.2.15/do... 实操 这里采用HAS+DCS+Vastbase的解决方案,详情可参考海量智库第8期|Vastbase G100核心技术介绍之…

网络基础--UPnP基本原理-CSDN博客

网络基础--UPnP基本原理-CSDN博客网络基础--UPnP基本原理-CSDN博客 https://blog.csdn.net/jisuanji111111/article/details/122108226 文章浏览阅读1.4w次,点赞3次,收藏22次。介绍UPNP基本知识点,比较全面。转载自华三文档。_upnp 2024-09-03 13:57:361、简介 UPnP是通用即…

敏捷项目管理工具:团队高效协作的关键

敏捷项目管理:团队高效协作的关键​ 在当今快节奏的市场环境中,企业必须具备快速响应变化的能力。无论是产品研发、软件开发还是市场推广,灵活应对变化和高效管理项目已成为企业成功的关键。于是,敏捷开发这一理念越来越多地被各行业团队采纳,成为了他们高效协作、及时交付…

首个标准+首家通过!大模型媒体处理评估,阿里云智能媒体服务“卓越级”通过

中国信通院近期正式发布《大模型驱动的媒体生产与处理》标准,阿里云智能媒体服务,以“首批首家”通过卓越级评估,并在9大模块50余项测评中表现为“满分”。中国信通院近期正式发布《大模型驱动的媒体生产与处理》标准,阿里云智能媒体服务,以“首批首家”通过卓越级评估,并…

MAC地址+网络层

进制 二进制和十六进制之间 1个16进制可以用4个二进制表示,1:4关系1111是否取值8 4 2 1 取值所代表的数值 在一台交换机上每台设备间的物理链路:不是直连 -- 直接连接 逻辑状态:都处于互联状态,处于一条链路上 MAC地址 由两部分组成,前24位代表该供应商代码,由IEEE管理…

Kubernetes Service与服务发现

1. Service资源基础概念 1.1 Service资源 Service是Kubernetes标准的API资源类型之一为动态的Pod资源提供近似静态的流量入口服务发现:通过标签选择器筛选同一名称空间下的Pod资源的标签,完成Pod筛选实际上是由与Service同名的Endpoint或EndpointSlice资源及控制器完成流量调…

Qt::BlockingQueuedConnection 与 QMetaCallEvent

Qt 创建连接类型如果是 Qt::BlockingQueuedConnection,即sender thread 与 receiver thread 不同, 但是要求 sender signal 与 receiver slot 执行是 不同线程间的同步行为。也即:在sender signal 发出后 sender线程 要 等待 receiver 线程的 slot 执行完后才能继续 向后执行…

设备地址

设备地址 BLE的设备地址可以使用公共地址(Public Device Adress)或者随机地址(Random Device Address),一个BLE至少使用一种地址类型,当然也可以同时使用两种地址类型。 公共地址和随机地址一样,都是48位(6字节),BLE设备地址关系如下:公共地址:从IEEE申请(购买),I…

扫码详见阳子公众号

https://mp.weixin.qq.com/mp/qrcode?scene=10000004&size=102&__biz=MzkwNzc0MjQ1MA==&mid=2247484006&idx=1&sn=43425e98c08a3887b090c927d89cbe40&send_time= 或直接扫码: