本帖最后由 风扫地 于 2018-11-12 12:07 编辑
分析例子.zip
(56.95 KB, 下载次数: 5)
看看这个附件的pdf文件在你那里能不能打开。
实验结论:
在vs2017 的cl编译器的处理情况(在其他编译器其他处理平台中未必有这些结论
1.堆栈不会不平衡,因为堆栈平衡机制是谁调用谁平衡,而不是被调用者来平衡堆栈;还有一些约定是由被调用者来平衡堆栈的(比如说stdcall方式),但如果是被调用者来平衡堆栈的话,本实验中无法体现。
2.堆栈虽然不会不平衡,但是多传参或者少传参都会造成数据错位,压多了还好只是可能错位,压少了,被调用者取数据就会取到别的数据区里面当成你传入的参数,这个参数只是读取越界还好,要是你还要写这个参数(或者少传的是一个指针,还用通过这个指针去访问别的空间),那就可能嗝屁了,访问到不是自己可以访问的数据区,后果无法预测;
3.返回值类型对不上的话数据会混乱,整数类型通过eax来返回,浮点型数据通过专用寄存器来返回,我的实验例子里面如果返回值要求是int,就直接从eax中取数据了(取到了printf函数的返回值),但实际上存储浮点型数据的专用寄存器中的结果并没有用到;
4.pdf中的专用栈空间应该修改为专用寄存器。
5.刚刚又在 test_function 加了__stdcall的关键字修饰,结果出了异常,堆栈不平衡了。
所以函数指针的使用要按规矩来,不要调戏编译器。
你要一个万能返回值和万能输入参数的函数指针类型太简单了,一般来说,其实一个 int32 型的数据都可以存下来(看汇编代码,就是存的函数首地址然后去call这个地址就调用成功了,地址值就是一个数,存一个数只要长度够,啥类型不行),用的时候取到这个数再强转成某个类型的函数指针就可以了,但是调用方式必须与函数声明的格式务必一致,务必一致。