vc编译器对 除法的优化
基本知识,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编译器对 除法的优化的更多相关文章
- 深入探究VC —— 编译器cl.exe(2)
这一章节介绍的全是VC编译器选项,option参数是cl.exe的编译选项,是cl.exe命令行参数中最复杂.也是最常用的.下面介绍一些常用的编译选项: 1.代码生成有关 这些选项将影响编译完成后生成 ...
- qtcreator添加绿色版VC编译器
在不装VS的情况下为qtcreator添加VC编译器和调试器 首先假设在D盘有VC6,VC2002,VC2003,VC2005,VC2008,VC2010,VC2013等绿色版的VC编译器,编译器的的 ...
- C# 编译器对局部变量的优化
C# 编译器对局部变量的优化 C# 的编译器可以对代码进行优化,所以,我们在写代码的时候,可以更多地考虑一下代码的易读性问题. 不考虑基本的对齐和换行美化.看一下局部变量优化问题. C# 示例代码 例 ...
- 深入探究VC —— 编译器cl.exe(1)
cl.exe的功能是将源代码文件编译为可提供链接器使用的obj对象文件.cl.exe命令行参数形式如下: CL (option...) file... [option | file]... [lib. ...
- 1.在VC编译器下面为什么每个头文件以及源文件都要包含“stdAfx.h”,那么stdAfx.h中到底存放了什么,用来做什么?
我们知道在windows平台下面很多的文件后缀名中都含有Afx,其实Afx是微软公司的一个技术研发团队名称,vc下的“stdAfx.h”和“stdAfx.cpp”文件就是有他们所研发出来的,为什么要这 ...
- Java编译器的2点优化
优化1 对于byte/short/char三种类型来说,如果右侧赋值的数值没有超过范围,那么javac编译器将会自动隐含地为我们补上一个(byte)(short)(char). 如果没有超过左侧的范围 ...
- java9的JShell小工具和编译器两种自动优化
一.按顺序逐步执行的脚本程序: 二.编译器自动优化 1.不超数据类型范围编译器自动添加强转操作: 2.一但发生运算,byte/short/char都会自动提升为Int,当只有常量参与运算时,编译器会先 ...
- 【原创】Java编译器对String的优化
首先看以下的代码: public static void main(String[] arge) { String str1 = new String("1234"); Strin ...
- vc编译器 msvcr.dll、msvcp.dll的含义和相关错误的处理
转自:http://blog.csdn.net/sptoor/article/details/6203376 很久没有写程式设计入门知识的相关文章了,这篇文章要来谈谈程式库 (Library) 连结, ...
随机推荐
- Redis哨兵参数
一.常用命令 sentinel的基本状态信息INFO 列出所有被监视的主服务器,以及这些主服务器的当前状态SENTINEL masters 列出指定主redis的从节点状态情况SENTINEL sla ...
- mysql排序字段为空的排在最后面
排序字段为orderid; 1.使用order by orderid desc实现降序时,orderid 为null数据的会排在数据的最后面: 但是,order by orderid升序时,order ...
- No module named 'lsb_release'
python3.7安装后提示 No module named 'lsb_release' 修改"/usr/bin/lsb_release" #!/usr/bin/python3.5 ...
- Java RMI实践
Java远程方法调用,即Java RMI(Java Remote Method Invocation).一种用于实现远程过程调用的应用程序编程接口.客户机上运行的程序可以调用服务器上的对象. 缺点:只 ...
- 【E2E】Intel AI DevCloud 的申请和登陆
参考:https://www.cnblogs.com/WaitingForU/p/9091096.html 一.注册 https://www.cnblogs.com/WaitingForU/p/909 ...
- pip安装各种模块
date: 2019-08-20 19:27:09 pip install requests pip install xpinyin pip install redis
- vscode 常用设置与插件推荐
1.Chinese (Simplified) Language Pack for Visual Studio Code 适用于 VS Code 的中文(简体)语言包 2.Color Info Visu ...
- ISO/IEC 9899:2011 条款6.5.1——基本表达式
6.5.1 基本表达式 语法 1.primary-expression: identifier constant string-literal ( expression ) generic ...
- stl中map的四种插入方法总结
stl中map的四种插入方法总结方法一:pair例:map<int, string> mp;mp.insert(pair<int,string>(1,"aaaaa&q ...
- 详解 C++11 lambda表达式
详解 C++11 lambda表达式 lambda表达式是函数式编程的基础.咱对于函数式编程也没有足够的理解,因此这里不敢胡言乱语,有兴趣的可以自己查找相关资料看下.这里只是介绍C++11中的la ...