基本知识,7/2 和 6/2 在计算机中的商都为3.C语言的除法不等同于数学意义中的除法。

C语言的除法。采用向零取整的方法。

-______________0_______________+

只有在除数为常量的情况下。编译器才会出现优化。

1、除数为正数,2的幂的除法

#include "stdafx.h"

int main(int argc, char* argv[])
{
int iNum = argc;
printf("%d\r\n", iNum / );
printf("%d\r\n", iNum / );
return ;
}

对应Release版本的反汇编如下:

push    esi
mov esi, dword ptr [esp+]
mov eax, esi
cdq
sub eax, edx
sar eax,
push eax
push test. ; ASCII "%d",CR,LF
call test.
mov eax, esi
add esp,
cdq
and edx,
add eax, edx
sar eax,
push eax
push test. ; ASCII "%d",CR,LF
call test.
add esp,
xor eax, eax
pop esi
retn

是不是感觉很奇怪,怎么没有了除法指令。查阅CPU手册。除法的指令周期数。大得吓人。具体值得根据cpu型号。翻阅 手册。

所以。编译器想尽办法。就是为了避免产生除法。提高效率。

mov     esi, dword ptr [esp+]
mov eax, esi
cdq
sub eax, edx
sar eax,

cdq 是把符号位扩展到 edx. 然后做加法。我们知道。对于被除数为正的情况,其值不变。除以2的幂。等于做 sar右移。

对于被除数为负的情况。那么由于sar右移。等同于向下取整。由于C语言是向零取整。所以。必须想办法下整转上整。就满足了C语言的向零取整。

于是公式来了。 a为被除数,n为2的幂.     (a + 2^n - 1)/2^n

对于 iNum / 2 那就是等于  (iNum + 2 - 1)/2 。常量折叠。等于(iNum + 1)/2。除以2等于sar右移一位。

那么就完美解决了除以2且无分歧的优化。指令的总周期。相对于div指令要减少很多。

在按照公式推导 iNum /4 的情况。(iNum + 2^2 - 1) / 2^2 。常量折叠。等于(iNum + 3) / 4。除以4等于sar右移两位。

对应的汇编代码如下。

mov     eax, esi
cdq
and edx,
add eax, edx
sar eax,

推荐本书籍:《C++反汇编与逆向分析技术揭秘》。

国内第一家从事软件逆向工程师培训的机构。http://www.51asm.com 强烈推荐!

vc编译器对 除法的优化的更多相关文章

  1. 深入探究VC —— 编译器cl.exe(2)

    这一章节介绍的全是VC编译器选项,option参数是cl.exe的编译选项,是cl.exe命令行参数中最复杂.也是最常用的.下面介绍一些常用的编译选项: 1.代码生成有关 这些选项将影响编译完成后生成 ...

  2. qtcreator添加绿色版VC编译器

    在不装VS的情况下为qtcreator添加VC编译器和调试器 首先假设在D盘有VC6,VC2002,VC2003,VC2005,VC2008,VC2010,VC2013等绿色版的VC编译器,编译器的的 ...

  3. C# 编译器对局部变量的优化

    C# 编译器对局部变量的优化 C# 的编译器可以对代码进行优化,所以,我们在写代码的时候,可以更多地考虑一下代码的易读性问题. 不考虑基本的对齐和换行美化.看一下局部变量优化问题. C# 示例代码 例 ...

  4. 深入探究VC —— 编译器cl.exe(1)

    cl.exe的功能是将源代码文件编译为可提供链接器使用的obj对象文件.cl.exe命令行参数形式如下: CL (option...) file... [option | file]... [lib. ...

  5. 1.在VC编译器下面为什么每个头文件以及源文件都要包含“stdAfx.h”,那么stdAfx.h中到底存放了什么,用来做什么?

    我们知道在windows平台下面很多的文件后缀名中都含有Afx,其实Afx是微软公司的一个技术研发团队名称,vc下的“stdAfx.h”和“stdAfx.cpp”文件就是有他们所研发出来的,为什么要这 ...

  6. Java编译器的2点优化

    优化1 对于byte/short/char三种类型来说,如果右侧赋值的数值没有超过范围,那么javac编译器将会自动隐含地为我们补上一个(byte)(short)(char). 如果没有超过左侧的范围 ...

  7. java9的JShell小工具和编译器两种自动优化

    一.按顺序逐步执行的脚本程序: 二.编译器自动优化 1.不超数据类型范围编译器自动添加强转操作: 2.一但发生运算,byte/short/char都会自动提升为Int,当只有常量参与运算时,编译器会先 ...

  8. 【原创】Java编译器对String的优化

    首先看以下的代码: public static void main(String[] arge) { String str1 = new String("1234"); Strin ...

  9. vc编译器 msvcr.dll、msvcp.dll的含义和相关错误的处理

    转自:http://blog.csdn.net/sptoor/article/details/6203376 很久没有写程式设计入门知识的相关文章了,这篇文章要来谈谈程式库 (Library) 连结, ...

随机推荐

  1. 模板 - 数据结构 - 链表/LinkedList

    一个只供删除的双向链表,为了简单不再引入head节点,而且也不进行next的套娃操作.空间使用略微多了一些,但是无伤大雅. struct LinkedList { static const int M ...

  2. 机器不学习:CNN入门讲解-为什么要有最后一层全连接

    哈哈哈,又到了讲段子的时间 准备好了吗? 今天要说的是CNN最后一层了,CNN入门就要讲完啦..... 先来一段官方的语言介绍全连接层(Fully Connected Layer) 全连接层常简称为 ...

  3. 《Linux设备驱动程序》编译LDD3的scull驱动问题总结***

    由于Linux内核版本更新的原因,LDD3(v2.6.10)提供的源码无法直接使用,下面是本人编译scull源码时出现的一些问题及解决方法.编译环境:Ubuntu 10.04 LTS(kernel v ...

  4. 【Json】Json分词器

    package com.hy; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNo ...

  5. PHP7 serialize_precision 配置不当导致 json_encode() 浮点小数溢出错误

    https://blog.csdn.net/moliyiran/article/details/81179825 感谢 @地狱星星:原因已找到, 该现象只出现在PHP 7.1+版本上建议使用默认值 s ...

  6. 关于golang中IO相关的Buffer类浅析

    io重要的接口 在介绍buffer之前,先来认识两个重要的接口,如下边所示: type Reader interface { Read(p []byte) (n int, err error) } t ...

  7. System.InvalidOperationException:“No coercion operator is defined between types 'System.Int16' and 'System.Boolean'.”

    modelBuilder.Entity<MentItems>().Property(e=>e.IsValid) .HasColumnType("bit(1)") ...

  8. 算法习题---4-8特别困的学生(UVa12108)

    一:题目 课堂上有n个学生(n<=),每个学生上课都会出现一个“清醒-睡眠”周期,其中第i个学生学习Ai分钟后睡眠Bi分钟,依次重复.其中在从清醒到睡眠时有一个条件:只有到全班睡眠人数大于清醒人 ...

  9. windows10 环境下的amqp安装步骤(图文)

    安装PHP扩展ampq 查看phpinfo()信息 下载ampq扩展 下载地址:http://pecl.php.net/package/amqp 选择一个dll版本下载,本文选择的是1.9.3 自己根 ...

  10. ABAP DEMO33 选择周的搜索帮助

    效果图 *&---------------------------------------------------------------------**& Report YCX_02 ...