C++反汇编->函数调用原理

来源:互联网 发布:mysql导出dmp文件 编辑:程序博客网 时间:2024/06/05 21:14

    VC6.0++函数调用方式有三种:

    分别为:

1._stdcall 方式

int _stdcall add1(int i,int j){cout<<"_stdcall out"<<endl;return i+j;}
0040158F      CC            INT3                                     ;  _stdcall 被调方平衡栈00401590 > >  55            PUSH EBP00401591   .  8BEC          MOV EBP,ESP00401593   .  83EC 40       SUB ESP,4000401596   .  53            PUSH EBX00401597   .  56            PUSH ESI00401598   .  57            PUSH EDI00401599   .  8D7D C0       LEA EDI,DWORD PTR SS:[EBP-40]0040159C   .  B9 10000000   MOV ECX,10004015A1   .  B8 CCCCCCCC   MOV EAX,CCCCCCCC004015A6   .  F3:AB         REP STOS DWORD PTR ES:[EDI]004015A8   .  68 CD104000   PUSH testcall.004010CD004015AD   .  68 1C004700   PUSH OFFSET testcall.??_C@_0N@HMEN@_stdc>;  _stdcall out004015B2   .  68 A0DE4700   PUSH OFFSET testcall.std::cout004015B7   .  E8 D8FCFFFF   CALL testcall.00401294004015BC   .  83C4 08       ADD ESP,8004015BF   .  8BC8          MOV ECX,EAX004015C1   .  E8 24FCFFFF   CALL testcall.004011EA004015C6   .  8B45 08       MOV EAX,DWORD PTR SS:[EBP+8]004015C9   .  0345 0C       ADD EAX,DWORD PTR SS:[EBP+C]004015CC   .  5F            POP EDI004015CD   .  5E            POP ESI004015CE   .  5B            POP EBX004015CF   .  83C4 40       ADD ESP,40004015D2   .  3BEC          CMP EBP,ESP004015D4   .  E8 D7F50100   CALL testcall.__chkesp004015D9   .  8BE5          MOV ESP,EBP004015DB   .  5D            POP EBP004015DC   .  C2 0800       RETN 8004015DF      CC            INT3
以上为DEBUG反汇编源码:


2._fastcall 方式

int _fastcall add2(int i, int j){cout<<"_fastcall out"<<endl;return i+j;}
004015FF      CC            INT3                                     ;  _fastcall 被调方 平衡栈00401600 > >  55            PUSH EBP00401601   .  8BEC          MOV EBP,ESP00401603   .  83EC 48       SUB ESP,4800401606   .  53            PUSH EBX00401607   .  56            PUSH ESI00401608   .  57            PUSH EDI00401609   .  51            PUSH ECX0040160A   .  8D7D B8       LEA EDI,DWORD PTR SS:[EBP-48]0040160D   .  B9 12000000   MOV ECX,1200401612   .  B8 CCCCCCCC   MOV EAX,CCCCCCCC00401617   .  F3:AB         REP STOS DWORD PTR ES:[EDI]00401619   .  59            POP ECX0040161A   .  8955 F8       MOV DWORD PTR SS:[EBP-8],EDX0040161D   .  894D FC       MOV DWORD PTR SS:[EBP-4],ECX00401620   .  68 CD104000   PUSH testcall.004010CD00401625   .  68 2C004700   PUSH OFFSET testcall.??_C@_0O@JLOO@_fast>;  _fastcall out0040162A   .  68 A0DE4700   PUSH OFFSET testcall.std::cout0040162F   .  E8 60FCFFFF   CALL testcall.0040129400401634   .  83C4 08       ADD ESP,800401637   .  8BC8          MOV ECX,EAX00401639   .  E8 ACFBFFFF   CALL testcall.004011EA0040163E   .  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]00401641   .  0345 F8       ADD EAX,DWORD PTR SS:[EBP-8]00401644   .  5F            POP EDI00401645   .  5E            POP ESI00401646   .  5B            POP EBX00401647   .  83C4 48       ADD ESP,480040164A   .  3BEC          CMP EBP,ESP0040164C   .  E8 5FF50100   CALL testcall.__chkesp00401651   .  8BE5          MOV ESP,EBP00401653   .  5D            POP EBP00401654   .  C3            RETN
以上为对应的DEBUG反汇编源码


3.cdecl 方式

int _cdecl add3(int i,int j){cout<<"_cdecl out"<<endl;    return i+j;}
00401670 > > \55            PUSH EBP                                 ;  保存栈底指针EBP00401671   .  8BEC          MOV EBP,ESP                              ;  调整当前栈底指针位置到栈顶00401673   .  83EC 40       SUB ESP,40                               ;  开辟栈空间  作为局部变量的存储空间00401676   .  53            PUSH EBX                                 ;  保存EBX寄存器00401677   .  56            PUSH ESI                                 ;  保存ESI寄存器00401678   .  57            PUSH EDI                                 ;  保存EDI寄存器00401679   .  8D7D C0       LEA EDI,DWORD PTR SS:[EBP-40]            ;  取出此函数 可用栈空间首地址0040167C   .  B9 10000000   MOV ECX,1000401681   .  B8 CCCCCCCC   MOV EAX,CCCCCCCC00401686   .  F3:AB         REP STOS DWORD PTR ES:[EDI]00401688   .  68 CD104000   PUSH testcall.004010CD0040168D   .  68 3C004700   PUSH OFFSET testcall.??_C@_0L@INPI@_cdec>;  _cdecl out00401692   .  68 A0DE4700   PUSH OFFSET testcall.std::cout00401697   .  E8 F8FBFFFF   CALL testcall.004012940040169C   .  83C4 08       ADD ESP,80040169F   .  8BC8          MOV ECX,EAX004016A1   .  E8 44FBFFFF   CALL testcall.004011EA004016A6   .  8B45 08       MOV EAX,DWORD PTR SS:[EBP+8]             ;  将EBP+8 处值 传送到EAX中004016A9   .  0345 0C       ADD EAX,DWORD PTR SS:[EBP+C]             ;  将EBP+C 处值与EAX值 相加004016AC   .  5F            POP EDI                                  ;  还原EDI 寄存器004016AD   .  5E            POP ESI                                  ;  还原ESI寄存器004016AE   .  5B            POP EBX                                  ;  还原EBX寄存器004016AF   .  83C4 40       ADD ESP,40                               ;  降低栈顶,此时局部变量空间被释放004016B2   .  3BEC          CMP EBP,ESP                              ;  检测栈平衡004016B4   .  E8 F7F40100   CALL testcall.__chkesp                   ;  进入栈平衡错误检测函数004016B9   .  8BE5          MOV ESP,EBP                              ;  还原ESP004016BB   .  5D            POP EBP004016BC   .  C3            RETN
以上为对应的DEBUG反汇编源码解释。


小结:

1.默认采用_cdecl方式。

2._fastcall方式 只是前两个参数用寄存器传递,后面的都采用栈传参方式。






0 0
原创粉丝点击