c语言 除法优化,【小课堂】汇编级除法优化
(1)比如 7 / 2 = 3 …… 1 -7 / 2= -3 …… -1
比较重要的是,余数的绝对值小于除数的绝对值,并且余数和被除数同正负
(2)由于 C语言 中除法是向0取整,也就是“截断除法”
不难发现,正数除以正数时,截断除法相当于向下取整(3.5 -> 3);而负数除以正数时,截断除法相当于向上取整( -3.5 -> -3 )
(3)除以2的k次幂通常会被优化成右移k位,这里考虑除以2时
用一个signed byte表示7,是00000111,右移一位变成00000011是3,是正确的
但是,考虑-7/2,-7是11111001,右移一位后变成11111100,这是-4,因为这是向下取整的结果,所以比正确的答案 -3少了1
代码中为了统一和效率,如果是32位的数字,会先右移31位扩展符号位。原先是正数则最高位是0,那么最后会变成32个0,也就是0,;原先是负数最高位是1,最后会变成32个1,也就是-1,暂且把这个扩展符号位后形成的数记作S,
那么,我们只需要把右移一位的结果,减去这个S,就可以得到正确的截断除法的值
7/2 = 7>>1 –(0) = 3 -7/2 =-7>>1 – (-1)= -3
(这一点在例题代码中会再次提到)
(4)当除以正数N,而N不是2的次幂时,编译器会生成一个magic_number(C),以使除法优化成乘法,提高效率
注意我强调的……(n,c)这个取值是成对的,一般取右移的位数n大于64,(理由一会再解释),比如n取72,这样C也就是常数了
图片中的证明表示:被除数(正数)乘以magic_number后再右移n位,即为除法的结果;如果是负数需要 +1
没错…就是第三点,最后统一减去符号扩展形成的数即可
好了,背景介绍的差不多了,来道CTFtime上的题目吧 :https://ctftime.org/task/5294?tdsourcetag=s_pcqq_aiomsg
简单看下,这就是除以N的除法优化代码,题目一般都是二分查找搞定flag的,这里作为一个较真的人……用数学来解一下
汇编代码中,0x49ea309a821a0d01就是magic_number
sar $0x3f,%rdi 因为long long是64位的,这里把函数参数rdi(被除数)右移63位,原先是正数则rdi变为0,原先是负数则rdi变为-1
imul %rdx之后,因为被除数被保存在了rax之中,因此乘积高位被放在rdx,低位被放在rax,最后我们发现乘积低位rax在后面没有被用到
原因是第四点背景提到的,n取值要大于64,这样128位的乘积只需要考虑rdx就可以了,乘积低64位rax被移位后必定为0,无需考虑,也提高了效率
后面因为rax作为返回值,x*c>>n被保存在了rax中,再sub rax,rdi
也就是我们提到的减去符号拓展形成的数
这个证明可能需要好好理解下(手写推导一次…)
好了现在我们看看flag(除数)是多少
因为我们最后只保留了乘积高位rdx,把rdx右移了0x30位
这就相当于把128位乘积右移了(64+0x30)==112位
那么,因为c = 2^n / y y = 2^n / c (其中c就是magic_number)
现在c已知,为0x49ea309a821a0d01,n已知,为112
算出除数y即可
注意的是这里虽然除法结果是精准的,但是反推除数时 python 的计算结果可能会有1的误差,这一点用二分算法时也会出现
其实除以正数还有第二种情况的优化算法,编译器根据C的值会有不同的选择,这就是《加密与解密》上除以正非2次幂的优化公式2,比如此题
以及除数为负数的稍复杂情况就不讨论了,相关内容可以看下《加密与解密》和《C++反汇编与逆向分析揭秘》,前者结论全面,后者推导较多
c语言 除法优化,【小课堂】汇编级除法优化相关推荐
- 运用计算机优化教学的方法,运用计算机优化数学课堂教学
运用计算机优化数学课堂教学 作者:教学方法 发表日期:2011-6-28 点击:次 来源:不详 运用计算机优化数学课堂教学运用计算机优化数学课堂教学 充分体现素质教育 湖南省长沙市芙蓉区育 ...
- 【汇编优化】之x86架构intrinsic优化
1.SSE Intrisic based on x86 x86架构下的优化有多种手段,常见的有纯汇编优化.inline汇编.Intrinsic优化.前两种对编译器的依赖比较大,跨平台(windows\ ...
- 嵌入式C语言优化小技巧
嵌入式C语言优化小技巧 1 概述 嵌入式系统是指完成一种或几种特定功能的计算机系统,具有自动化程度高,响应速度快等优点,目前已广泛应用于消费电子,工业控制等领域.嵌入式系统受其使用的硬件以及运行环境的 ...
- 小甲鱼c语言课后作业_知识,就是力量——山财“学习小课堂”助你蓄力
编者按 少年,你渴望 知识的力量 吗? 我们有山财最全的学习秘籍, 只待你的耐心翻阅与潜心修炼! 接下来,就让我们一起查收学习干货~ 内容摘要 本系列推送分为 [悦览篇][干货篇][招募篇] 三大模块 ...
- 如何用r语言搜集报表_基迪奥免费小课堂——如何用R语言绘制GSEA plot
常见的基因功能富集分析方法可以认为分两代. (1)第一代:基于目标基因集预筛选的功能富集分析方法 基本步骤包括两步: (a)从背景基因集合,按照一定固定阈值(例如,是否差异显著)筛选目标基因集.这属于 ...
- [c语言]小课堂 day5
这是今天的小课堂题目: #include<stdio.h>int main() {int a = -1;unsigned int n_a = a;printf("十进制 a = ...
- mysql百万级去重_mysql优化小技巧之去除重复项(百万级数据)
mysql优化小技巧之去除重复项(百万级数据) 发布时间:2018-06-11 11:54, 浏览次数:482 , 标签: mysql 说到这个去重,脑仁不禁得一疼,尤其是出具量比较大的时候.毕竟咱不 ...
- C语言嵌入式系统编程修炼之道——性能优化篇
C语言嵌入式系统编程修炼之道--性能优化篇 作者:宋宝华 e-mail:[email]21cnbao@21cn.com[/email] 1.使用宏定义 在C语言中,宏是产生内嵌代码的唯一方法.对于嵌 ...
- 这10种神级性能优化手段,你用过几个?
作者:code2life 来源:https://code2life.top/2020/08/15/0055-performance/ 上篇 引言:取与舍 软件设计开发某种意义上是"取&quo ...
- 10种神级性能优化手段
本文来自 https://mp.weixin.qq.com/s/sYgyB87ePDvBjpVXKs7kZw,郎涯进行简单排版与补充 上篇 引言:取与舍 软件设计开发某种意义上是**"取&q ...
最新文章
- 复旦教授:在一般院校里,我可能连当副教授都不够格
- 判断一颗二叉树是否为搜索二叉树和完全二叉树
- laravel5.6 php,Laravel5.6中的队列简单使用
- 接口的特点 java 1614101071
- 大唐波斯将军 机器人_跑到大唐的萨珊波斯遗民
- 内核中的UDP socket流程(3)(4)——sock_create
- SpringBoot之Filter过滤器的实现及排序问题
- 6位大师浅谈未来三年大数据的发展
- Pytorch 的迁移学习的理解
- assemblyinstaller 无法启动计算机.上的服务,本地计算机上的Windows Search服务启动然后停止 | MOS86...
- MFC中 使用Tab Control 控件在对话框中添加属性页
- 广度优先搜索nodeHDU/HDOJ 1242 Rescue 典型的迷宫广度优先搜索题
- 解决 Refused to display in a frame because it set 'X-Frame-Options' to 'deny'.问题
- AI面试锦囊|网易互娱AI Lab人工智能研究工程师两面分享
- 智能网联汽车信息安全研究报告
- 怎么把ppt转化成图片
- html中首页的概念,网页开发网页的相关概念你知道吗?
- jkd环境安装脚本(jdk-8u201-linux-x64.tar.gz)
- 驱动器能耗制动和制动电阻
- codeforces1000a csdn-博客