您的位置:首页 > 其它

反汇编分析__stdcall和__cdecl的异同

2017-01-05 07:29 337 查看
C++代码如下:
.h头文件

#pragma once

#ifdef DLLTestAPI

#else
#define DLLTestAPI _declspec(dllimport)
#endif

int DLLTestAPI __stdcall add(int, int);

int DLLTestAPI __cdecl subtract(int, int);

.cpp代码文件

#define DLLTestAPI _declspec(dllexport)

#include "Test.h"

int __stdcall add(int a, int b)

int __cdecl subtract(int a, int b)
100115D0 55 PUSH EBP
100115D1 8BEC MOV EBP,ESP
100115D3 81EC C0000000 SUB ESP,0C0
100115D9 53 PUSH EBX
100115DA 56 PUSH ESI
100115DB 57 PUSH EDI
100115DC 8DBD 40FFFFFF LEA EDI,DWORD PTR SS:[EBP-C0]
100115E2 B9 30000000 MOV ECX,30
100115E7 B8 CCCCCCCC MOV EAX,CCCCCCCC
100115EC F3:AB REP STOS DWORD PTR ES:[EDI]
100115EE 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
100115F1 0345 0C ADD EAX,DWORD PTR SS:[EBP+C]
100115F4 5F POP EDI
100115F5 5E POP ESI
100115F6 5B POP EBX
100115F7 8BE5 MOV ESP,EBP
100115F9 5D POP EBP
100115FA C2 0800 RETN 8

subtract方法:

10011610 55 PUSH EBP
10011611 8BEC MOV EBP,ESP
10011613 81EC C0000000 SUB ESP,0C0
10011619 53 PUSH EBX
1001161A 56 PUSH ESI
1001161B 57 PUSH EDI
1001161C 8DBD 40FFFFFF LEA EDI,DWORD PTR SS:[EBP-C0]
10011622 B9 30000000 MOV ECX,30
10011627 B8 CCCCCCCC MOV EAX,CCCCCCCC
1001162C F3:AB REP STOS DWORD PTR ES:[EDI]
1001162E 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
10011631 2B45 0C SUB EAX,DWORD PTR SS:[EBP+C]
10011634 5F POP EDI
10011635 5E POP ESI
10011636 5B POP EBX
10011637 8BE5 MOV ESP,EBP
10011639 5D POP EBP
1001163A C3 RETN

大家已经看到了,他们的唯一区别是:
使用__stdcall修饰的add方法,最后的RETN指令的操作数是8,而使用__cdecl修饰的subtract方法,最后的RETN指令没有操作数。

RETN指令的操作数为什么是8呢,原因也很简单,就是add方法有两个int参数,也就是说压栈的时候压入了两个字节,正好8位,RETN 8的意思应该是让栈顶指针ESP向后移动8位。
http://blog.csdn.net/songjinshi/article/details/8442829
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: