VC++ 得到的函数地址与实际函数地址不一致的原因。
我想试验一个计算汇编指令长度的代码是否正确,因而写了如下code进行验证,但结果非常奇怪
#include <stdio.h>
#include <Windows.h> int add(int a,int b)
{
return a+b;
} extern ULONG GetOpCodeSize(PVOID Start); int main(int argc,char* argv[])
{
int c = add(1,2);
PVOID pFunc = (void*)add;
ULONG ulResult = GetOpCodeSize(pFunc);
return 0;
}
发现,返回的汇编指令长度等于5,然而,反汇编看到add的函数体为:

明显第一条指令是长度等于1。
debug发现:pFunc != add !!,而在pFunc地址处的指令如下:

原来VC++ debug模式下在调用函数之前需要通过一个中转,原因在于VC++的Incremental Link :
什么是Incremental Link Table呢?
假如一个程序有连续两个foo和bar (所谓连续,就是他们编译连接之后函数体连续存放), foo入口位置在0x0400,长度为0x200个字节,那么bar入口就应该在0x0600 = 0x0400+0x0200。程序员在开发的时候总是频繁的修改code然后build,假如程序员在foo里面增加了一些内容,现在foo函数体占 0x300个字节了,bar的入口也就只好往后移0x100变成了0x0700,这样就有一个问题,如果foo在程序中被调用了n次,那么linker不得不修改这n个函数调用点,虽然linker不嫌累,但是link时间长了,程序员会觉得不爽。所以MSVC在Debug版的build,不会让各个函数体之间这么紧凑,每个函数体后都有padding(全是汇编代码int 3,作用是引发中断,这样因为古怪原因运行到不该运行的padding部分,会发生异常),有了这些padding,就可以一定程度上缓解上面提到的问题,不过当函数增加内容太多超过padding,还是有问题,怎么办呢?MSVC在Debug build中用上了Incremental Link Table, ILT其实就是一串jmp语句,每个jmp语句对应一个函数,jmp的目的地就是函数的入口点,和没有ILT的区别是,现在对函数的调用不是直接call 到函数入口点了,而是call到ILT中对应的位置,而这个位置上什么也不做,直接jmp到函数中去。这样的好处是,当一个函数入口地址改变时,只要修改 ILT中对应值就搞定了,用不着修改每一个调用位置,用一个冗余的ITL把时间复杂度从O(n)将为O(1),值得,当然Debug版的二进制文件会稍大稍慢,Release版不会用上ILT。
最后disable Incremental Link 之后,结果是1,正确!
VC++ 得到的函数地址与实际函数地址不一致的原因。的更多相关文章
- VC.【转】采用_beginthread/_beginthreadex函数创建多线程
https://blog.csdn.net/cbnotes/article/details/8331632 还可以看这个网址的内容:[多线程]VC6使用_beginthread开启多线程的方法-技术宅 ...
- 介绍了如何取成员函数的地址以及调用该地址:C++
摘要:介绍了如何取成员函数的地址以及调用该地址. 关键字:C++成员函数 this指针 调用约定 一.成员函数指针的用法 在C++中,成员函数的指针是个比较特殊的东西.对普通的函数指针来说,可以视为一 ...
- VC与JavaScript交互(二) --- 调用JS函数
这一章,我们来动手实践VC调用JS函数. 我们动手写一个HTML,其中包含这样一段JS代码: //[html] <script type="text/javascript"& ...
- VC生成lib的_stdcall函数名与mingw生成的不一致
Qt Creator在Windows系统中,怎样链接VC生成的动态链接库 这个问题曾经困扰了我一整天.我想的是按照VC中的方法,增加include文件,增加lib文件,然后编译即可.谁知链接时总是出现 ...
- Laravel 5.2+ 使用url()全局函数返回前一个页面的地址
注意:文章标题中5.2+表示该文章内容可向上兼容,适用于Laravel版本5.2及更高(目前最新为5.6),但不可向下兼容,即不适用于5.2版本以下.推荐大家花一点点时间,将自己的Laravel更新至 ...
- vc MFC 通过IDispatch调用默认成员函数
CComPtr<IDispatch> spDisp(IDispatch *); if(!spDisp) return; DISPPARAMS dispParam={0}; //没有参数 V ...
- postgresql----网络地址类型和函数
本人对网络这块实在是搞不清楚,要是能有人推荐一下资料就好了!不知道有没有跟我一样呢?!所以在这里先贴一点从其他地方搞来的一些IPv4的东东. IPv4主要包括一下5类地址 A类: 0 7位 网络号 2 ...
- 旧文备份:VC中嵌入NASM编写的汇编函数
在公司开发的RT下没法使用C库,并且替代库函数没有几个,需要用到setjmp和longjmp函数,没办法,只能自己想办法了,上sourceforge淘换到一个小日本的工程,提供这两个函数的替代源码,名 ...
- VC++的函数指针和回调函数 及友元函数
什么是函数指针 函数指针是指向函数的指针变量.也就是说,它是一个指针变量,而且该指针指向一个函数. 对于指针变量来说,它的值是它指向的变量的地址.举个例子:指针变量pi是指向一个整型变量i的指针,则变 ...
- VC 使用msxml6.dll动态链接库中的函数读写XML文件
VC 使用msxml6.dll动态链接库中的函数读写XML文件 目录 1 引言 2 .dll使用方法 3 常用函数总结 4 实例应用 5 运行效果预览 6 补充说明 7 不足之处 8 更新 引言: ...
随机推荐
- 【codeforces #282(div 1)】AB题解
A. Treasure time limit per test 2 seconds memory limit per test 256 megabytes input standard input o ...
- PJOI PKU Campus 2011 B:A Problem about Tree LCA 求随意点x为根的y的父节点
题目链接:点击打开链接 题意:给定n个点 m个询问 以下n-1行给定一棵树 m个询问 x y 问把树转成以x为根 y的父节点是谁 第一种情况lca==y那就是x的第 dep[x] - dep[y] - ...
- 实用且免费API接口2
之前已经整理过一些免费API,现在在知乎专栏上看到别人整理的一些实用免费API,有一些是没有重复的,因此也搬过来. 今天的内容,很适合你去做一些好玩.实用的东西出来. 先来科普个概念,开放应用程序的A ...
- vue 项目中 自定义 webpack 的 配置文件(webpack.config.babel.js)
webpack.config.babel.js,这样命名是想让webpack在编译的时候自动识别es6的语法,现在貌似不需要这样命名了,之前用webpack1.x的时候貌似是需要的 let path ...
- openerp-server.conf 中配置 dbfilter 参数无效的解决办法
来自:http://shine-it.net/index.php/topic,14517.html 以前就发现过这个问题, 今天重新在群里同大家讨论了一下. 有时候可能我们希望用户不从登陆界面的账套选 ...
- /proc/meminfo详解 = /nmon analysis --MEM
memtotal hightotal lowtotal swaptotal memfree highfree lowfree swapfree memshared cached active bigf ...
- 程序员取悦女票的正确姿势---Tip1(iOS美容篇)
代码地址如下:http://www.demodashi.com/demo/11695.html 前言 女孩子都喜欢用美图工具进行图片美容,近来无事时,特意为某人写了个自定义图片滤镜生成器,安装到手机即 ...
- 编写C函数的技术-《lua程序设计》 27章 学习
1.数组操作 void lua_rawgeti(lua_State * L ,int index,int key) void lua_rewseti(lua_State * L,int index,i ...
- asp.net+mvc+easyui+sqlite 简单用户系统学习之旅(六)—— 简单过滤器的使用
有些同学喜欢在测试或运行项目时,直接跳转页面到Home/Index下,但本次项目直接输入Home/Index则会报错 因为home/index中有个user.name参数,如果启动项目后直接跳转到ho ...
- jQuery find() 搜索所有段落中的后代 C# find() 第一个匹配元素 Func 有返回值 Action是没有返回值 Predicate 只有一个参数且返回值为bool 表达式树Expression
所有p后代span Id为 TotalProject 的 select 标签 的后代 option标签 为选中的 text using System; using System.Collections ...