11-07除法

代码分析:分段,以块为单位看代码,逐个击破

流水线优化:在不影响结果的前提下,排列指令顺序,提高并行程度


除法

变化一

     如果除数是变量,只能使用除法指令,有符号是idiv,无符号是div

这是经过数学论证的,当除数位置是没有优化的余地的

变化二

     除数不是变量,且除数是2的幂

1.在无符号的情况下,采取向下取整的除法,,一般直接使用右移指令


图片.png

2.有符号的情况下,需要经过数学推导:

IMG_2861.JPG

数学除法会产生小数,C语言计算产生的误差只要在0- |1/b| 之间的范围,可以利用这个推导来忽略误差

IMG_2862.JPG

由以上推导,处理有符号数的时候,例如

图片.png

编译器的优化过程以推导7作为基础

IMG_2863.JPG

可是,如何将 n > 0 和 n < 0 这两个分支优化,编译器采取的思路是利用cdq配合and指令

cdq                         ;符号拓展,将eax的符号拓展到edx,edx要么位0xffffffff要么为0
and         edx,7           ;利用与运算,若n > 0 ,edx = 0,   n < 0, edx = 7
add         eax,edx
sar         eax,3

定式:

cdq
and edx, immA
add eax, edx
sar eax, immB

验证:

(2^immB) -1 = immA
若不相等,则可能是作者内联汇编挖的坑,因为c语言语法是不会产生cdq指令的

还原:

eax / (2^immB)

     除数不是变量,且除数不是2的幂

Debug:不做有优化
Release:

推导:

IMG_2864.JPG

m = 2^n / c
n由编译器决定,一般16位环境从16开始,32位环境从32开始,以此类推。
所以2^n为常量
c为常量
n的取值由c决定,需要满足误差小于1/c
所以m为常量,又称为MagicNumber,这个值由编译器编译时产生

又因为 a*m = edx. eax
有可能直接使用edx,那么这就是结果 >>32 位
所以最后的结果需要以edx做移位,
所以edx的移位位数需要加上32

定式

mov eax, MagicNumber
imul ....
sar edx, ...
mov reg, edx
shr reg, 1fh
add edx, reg

还原

o = 2^n / c
n从右移的次数得到,MagicNumber作为c,代入公式求解到除数近似值,还原除法原型

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 8086汇编 本笔记是笔者观看小甲鱼老师(鱼C论坛)《零基础入门学习汇编语言》系列视频的笔记,在此感谢他和像他一样...
    Gibbs基阅读 37,469评论 8 114
  • 王爽汇编全书知识点大纲 第一章 基础知识 机器语言 汇编语言的产生 汇编语言的组成 存储器 cpu对存储器的读写 ...
    2c3ba901516f阅读 2,456评论 0 1
  • 有哪些值得借鉴的行走社会的经验? 1、能用钱解决的事情,千万不要用人情。 2、好听的话别当真,难听的话别走心。 3...
    zhangBennett阅读 252评论 0 0
  • 心心念念一年的人也可以说放下就放下。 知道一切都回不去了,所以我也不再报希望。或许从来就不曾有过希望。zz yl对...
    木刻茉莉阅读 105评论 0 0
  • 上上周,因为某种机缘巧合,我去了趟养老院。 没去之前,养老院在我心里是长这样的: 不长上面那样也应该长这样: 结果...
    鬼才肉兔几阅读 2,465评论 33 62