(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语言 除法优化,【小课堂】汇编级除法优化相关推荐

  1. 运用计算机优化教学的方法,运用计算机优化数学课堂教学

    运用计算机优化数学课堂教学 作者:教学方法   发表日期:2011-6-28   点击:次   来源:不详 运用计算机优化数学课堂教学运用计算机优化数学课堂教学 充分体现素质教育 湖南省长沙市芙蓉区育 ...

  2. 【汇编优化】之x86架构intrinsic优化

    1.SSE Intrisic based on x86 x86架构下的优化有多种手段,常见的有纯汇编优化.inline汇编.Intrinsic优化.前两种对编译器的依赖比较大,跨平台(windows\ ...

  3. 嵌入式C语言优化小技巧

    嵌入式C语言优化小技巧 1 概述 嵌入式系统是指完成一种或几种特定功能的计算机系统,具有自动化程度高,响应速度快等优点,目前已广泛应用于消费电子,工业控制等领域.嵌入式系统受其使用的硬件以及运行环境的 ...

  4. 小甲鱼c语言课后作业_知识,就是力量——山财“学习小课堂”助你蓄力

    编者按 少年,你渴望 知识的力量 吗? 我们有山财最全的学习秘籍, 只待你的耐心翻阅与潜心修炼! 接下来,就让我们一起查收学习干货~ 内容摘要 本系列推送分为 [悦览篇][干货篇][招募篇] 三大模块 ...

  5. 如何用r语言搜集报表_基迪奥免费小课堂——如何用R语言绘制GSEA plot

    常见的基因功能富集分析方法可以认为分两代. (1)第一代:基于目标基因集预筛选的功能富集分析方法 基本步骤包括两步: (a)从背景基因集合,按照一定固定阈值(例如,是否差异显著)筛选目标基因集.这属于 ...

  6. [c语言]小课堂 day5

    这是今天的小课堂题目: #include<stdio.h>int main() {int a = -1;unsigned int n_a = a;printf("十进制 a = ...

  7. mysql百万级去重_mysql优化小技巧之去除重复项(百万级数据)

    mysql优化小技巧之去除重复项(百万级数据) 发布时间:2018-06-11 11:54, 浏览次数:482 , 标签: mysql 说到这个去重,脑仁不禁得一疼,尤其是出具量比较大的时候.毕竟咱不 ...

  8. C语言嵌入式系统编程修炼之道——性能优化篇

    C语言嵌入式系统编程修炼之道--性能优化篇 作者:宋宝华  e-mail:[email]21cnbao@21cn.com[/email] 1.使用宏定义 在C语言中,宏是产生内嵌代码的唯一方法.对于嵌 ...

  9. 这10种神级性能优化手段,你用过几个?

    作者:code2life 来源:https://code2life.top/2020/08/15/0055-performance/ 上篇 引言:取与舍 软件设计开发某种意义上是"取&quo ...

  10. 10种神级性能优化手段

    本文来自 https://mp.weixin.qq.com/s/sYgyB87ePDvBjpVXKs7kZw,郎涯进行简单排版与补充 上篇 引言:取与舍 软件设计开发某种意义上是**"取&q ...

最新文章

  1. 复旦教授:在一般院校里,我可能连当副教授都不够格
  2. 判断一颗二叉树是否为搜索二叉树和完全二叉树
  3. laravel5.6 php,Laravel5.6中的队列简单使用
  4. 接口的特点 java 1614101071
  5. 大唐波斯将军 机器人_跑到大唐的萨珊波斯遗民
  6. 内核中的UDP socket流程(3)(4)——sock_create
  7. SpringBoot之Filter过滤器的实现及排序问题
  8. 6位大师浅谈未来三年大数据的发展
  9. Pytorch 的迁移学习的理解
  10. assemblyinstaller 无法启动计算机.上的服务,本地计算机上的Windows Search服务启动然后停止 | MOS86...
  11. MFC中 使用Tab Control 控件在对话框中添加属性页
  12. 广度优先搜索nodeHDU/HDOJ 1242 Rescue 典型的迷宫广度优先搜索题
  13. 解决 Refused to display in a frame because it set 'X-Frame-Options' to 'deny'.问题
  14. AI面试锦囊|网易互娱AI Lab人工智能研究工程师两面分享
  15. 智能网联汽车信息安全研究报告
  16. 怎么把ppt转化成图片
  17. html中首页的概念,网页开发网页的相关概念你知道吗?
  18. jkd环境安装脚本(jdk-8u201-linux-x64.tar.gz)
  19. 驱动器能耗制动和制动电阻
  20. codeforces1000a csdn-博客

热门文章

  1. tomcat6到tomcat9解压版(64位)随意下载
  2. Android -- WiFi的NUD检测机制浅析
  3. 程序算法面试 题目汇总 算法题 推理题 规律题
  4. 手把手教你做个人 app
  5. 我国的省级行政区中,哪些邻省最多,哪些最少?
  6. 《C专家编程》学习笔记(对链接的思考)
  7. android 修改手机型号加点,修改Android设备信息,如修改手机型号为iPhone7黄金土豪版! -电脑资料...
  8. 《女士品茶》读书笔记
  9. 单相智能电表(DL/T645-2007协议)
  10. Emmagee——Android性能测试工具