首页
社区
课程
招聘
[旧帖] [求助]关于C++内联函数的 0.00雪花
发表于: 2010-11-29 10:18 1072

[旧帖] [求助]关于C++内联函数的 0.00雪花

2010-11-29 10:18
1072
刚学C++的时候老师就跟我们说内联函数“类似宏替换,使用函数体替换调用处的函数名”,但是我编了一程序,VC6编译,默认的代码优化方式,然后反汇编一下发现貌似是一个不折不扣的普通函数调用, 可以告诉我是什么原因吗? 或者我写的代码有什么问题?

代码如下:
#include <stdio.h>

class myClass
{
public:
        myClass(int a, int b);
        inline int Add()
        {
                return m+n;
        }
private:
        int m;
        int n;
};

myClass::myClass(int a, int b):m(a), n(b)
{
}

int main()
{
        myClass myPtr(1, 2);
        myPtr.Add();
        return 0;
}

反汇编代码如下:

00401070  /> \55            PUSH EBP
00401071  |.  8BEC          MOV EBP,ESP
00401073  |.  83EC 48       SUB ESP,48
00401076  |.  53            PUSH EBX
00401077  |.  56            PUSH ESI
00401078  |.  57            PUSH EDI
00401079  |.  8D7D B8       LEA EDI,DWORD PTR SS:[EBP-48]
0040107C  |.  B9 12000000   MOV ECX,12
00401081  |.  B8 CCCCCCCC   MOV EAX,CCCCCCCC
00401086  |.  F3:AB         REP STOS DWORD PTR ES:[EDI]
00401088  |.  6A 02         PUSH 2
0040108A  |.  6A 01         PUSH 1
0040108C  |.  8D4D F8       LEA ECX,DWORD PTR SS:[EBP-8]
0040108F  |.  E8 80FFFFFF   CALL DisasmCl.00401014
00401094  |.  8D4D F8       LEA ECX,DWORD PTR SS:[EBP-8]      ;this指针
00401097  |.  E8 7DFFFFFF   CALL DisasmCl.00401019               ;调用的内联函数
0040109C  |.  33C0          XOR EAX,EAX
0040109E  |.  5F            POP EDI
0040109F  |.  5E            POP ESI
004010A0  |.  5B            POP EBX
004010A1  |.  83C4 48       ADD ESP,48
004010A4  |.  3BEC          CMP EBP,ESP
004010A6  |.  E8 75000000   CALL DisasmCl.00401120
004010AB  |.  8BE5          MOV ESP,EBP
004010AD  |.  5D            POP EBP
004010AE  \.  C3            RETN

00401019   $ /E9 92000000   JMP DisasmCl.004010B0             ;调用内联函数过程

004010B0  /> \55            PUSH EBP
004010B1  |.  8BEC          MOV EBP,ESP
004010B3  |.  83EC 44       SUB ESP,44
004010B6  |.  53            PUSH EBX
004010B7  |.  56            PUSH ESI
004010B8  |.  57            PUSH EDI
004010B9  |.  51            PUSH ECX
004010BA  |.  8D7D BC       LEA EDI,DWORD PTR SS:[EBP-44]
004010BD  |.  B9 11000000   MOV ECX,11
004010C2  |.  B8 CCCCCCCC   MOV EAX,CCCCCCCC
004010C7  |.  F3:AB         REP STOS DWORD PTR ES:[EDI]
004010C9  |.  59            POP ECX
004010CA  |.  894D FC       MOV DWORD PTR SS:[EBP-4],ECX
004010CD  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]
004010D0  |.  8B00          MOV EAX,DWORD PTR DS:[EAX]
004010D2  |.  8B4D FC       MOV ECX,DWORD PTR SS:[EBP-4]
004010D5  |.  0341 04       ADD EAX,DWORD PTR DS:[ECX+4]
004010D8  |.  5F            POP EDI
004010D9  |.  5E            POP ESI
004010DA  |.  5B            POP EBX
004010DB  |.  8BE5          MOV ESP,EBP
004010DD  |.  5D            POP EBP
004010DE  \.  C3            RETN

希望高手不吝赐教,感激不尽

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 191
活跃值: (345)
能力值: ( LV9,RANK:450 )
在线值:
发帖
回帖
粉丝
2
myClass 函数如果在类内完成才能被内联.你把函数定义和实现都放到类内完成.

比如

class xxx
{
public:
  myClass(int a, int b){你要内联的代码};
}
2010-11-29 11:16
0
雪    币: 47
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我的Add函数是在类内定义和实现的, 上面贴的那段反汇编代码是Add的反汇编代码
2010-11-29 11:55
0
雪    币: 16
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
VS里面Debug模式是不做任何代码优化的。
所以你在Debug编译模式下,无论搞不搞online其实都是一样的,统统当作普通函数处理。
只有在Release模式下,切优化online打开的情况下,编译器才会给你内联的。

由于VSRelease模式下,无法设置断点进行调试,所以只能借助第三方反汇编工具来查看。

即使看不到,你可以看看使用了Online之后编译出来的执行文件都会更小一些。而不使用文件会更大一些,可见确实是有区别的。
2010-11-29 12:06
0
雪    币: 16
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
我的测试代码如下:编译环境VS2010,采用OllyICE进行反汇编,对比如下:
#include "stdafx.h"

inline void Add()
{
        int a=20;
       
}
int _tmain(int argc, _TCHAR* argv[])
{
        Add();
        return 0;
}

====没有使用online==============
00401000  /$  55            push    ebp
00401001  |.  8BEC          mov     ebp, esp
00401003  |.  51            push    ecx
00401004  |.  C745 FC 14000>mov     dword ptr [ebp-4], 14
0040100B  |.  8BE5          mov     esp, ebp
0040100D  |.  5D            pop     ebp
0040100E  \.  C3            retn
0040100F      CC            int3
00401010  /$  55            push    ebp
00401011  |.  8BEC          mov     ebp, esp
00401013  |.  E8 E8FFFFFF   call    00401000
00401018  |.  33C0          xor     eax, eax
0040101A  |.  5D            pop     ebp
0040101B  \.  C3            retn

====使用了online=====================
00401000  /$  55            push    ebp
00401001  |.  8BEC          mov     ebp, esp
00401003  |.  51            push    ecx
00401004  |.  C745 FC 14000>mov     dword ptr [ebp-4], 14
0040100B  |.  33C0          xor     eax, eax
0040100D  |.  8BE5          mov     esp, ebp
0040100F  |.  5D            pop     ebp
00401010  \.  C3            retn
00401011   .  3B0D 00304000 cmp     ecx, dword ptr [403000]
00401017   .  75 02         jnz     short 0040101B
00401019   .  F3:           prefix rep:
0040101A   .  C3            retn
0040101B   >  E9 98020000   jmp     004012B8
2010-11-29 12:45
0
雪    币: 8
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
学习
2010-11-29 13:52
0
雪    币: 47
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
谢谢楼上的高手指点, 我换成Release模式,然后用OD反汇编, 的确是把inline里的代码贴到了调用函数里, 受益匪浅, 感激不尽
2010-11-29 13:58
0
游客
登录 | 注册 方可回帖
返回
//