天天看点

反汇编分析__stdcall和__cdecl的异同

C++代码如下:

.h头文件

反汇编分析__stdcall和__cdecl的异同

#pragma once

反汇编分析__stdcall和__cdecl的异同
反汇编分析__stdcall和__cdecl的异同

#ifdef DLLTestAPI

反汇编分析__stdcall和__cdecl的异同
反汇编分析__stdcall和__cdecl的异同

#else

反汇编分析__stdcall和__cdecl的异同

#define DLLTestAPI _declspec(dllimport)

反汇编分析__stdcall和__cdecl的异同

#endif

反汇编分析__stdcall和__cdecl的异同
反汇编分析__stdcall和__cdecl的异同

int DLLTestAPI __stdcall add(int, int);

反汇编分析__stdcall和__cdecl的异同
反汇编分析__stdcall和__cdecl的异同

int DLLTestAPI __cdecl subtract(int, int);

.cpp代码文件

反汇编分析__stdcall和__cdecl的异同

#define DLLTestAPI _declspec(dllexport)

反汇编分析__stdcall和__cdecl的异同
反汇编分析__stdcall和__cdecl的异同

#include "Test.h"

反汇编分析__stdcall和__cdecl的异同
反汇编分析__stdcall和__cdecl的异同

int __stdcall add(int a, int b)

反汇编分析__stdcall和__cdecl的异同

{

反汇编分析__stdcall和__cdecl的异同

    return a + b;

反汇编分析__stdcall和__cdecl的异同

}

反汇编分析__stdcall和__cdecl的异同
反汇编分析__stdcall和__cdecl的异同

int __cdecl subtract(int a, int b)

反汇编分析__stdcall和__cdecl的异同
反汇编分析__stdcall和__cdecl的异同

    return a - b;

反汇编分析__stdcall和__cdecl的异同

可以看到 add方法是使用__stdcall修饰的,而subtract方法是使用__cdecl修饰的。

反汇编后得到的汇编代码如下

add方法:

反汇编分析__stdcall和__cdecl的异同

100115D0    55              PUSH EBP

反汇编分析__stdcall和__cdecl的异同

100115D1    8BEC            MOV EBP,ESP

反汇编分析__stdcall和__cdecl的异同

100115D3    81EC C0000000   SUB ESP,0C0

反汇编分析__stdcall和__cdecl的异同

100115D9    53              PUSH EBX

反汇编分析__stdcall和__cdecl的异同

100115DA    56              PUSH ESI

反汇编分析__stdcall和__cdecl的异同

100115DB    57              PUSH EDI

反汇编分析__stdcall和__cdecl的异同

100115DC    8DBD 40FFFFFF   LEA EDI,DWORD PTR SS:[EBP-C0]

反汇编分析__stdcall和__cdecl的异同

100115E2    B9 30000000     MOV ECX,30

反汇编分析__stdcall和__cdecl的异同

100115E7    B8 CCCCCCCC     MOV EAX,CCCCCCCC

反汇编分析__stdcall和__cdecl的异同

100115EC    F3:AB           REP STOS DWORD PTR ES:[EDI]

反汇编分析__stdcall和__cdecl的异同

100115EE    8B45 08         MOV EAX,DWORD PTR SS:[EBP+8]

反汇编分析__stdcall和__cdecl的异同

100115F1    0345 0C         ADD EAX,DWORD PTR SS:[EBP+C]

反汇编分析__stdcall和__cdecl的异同

100115F4    5F              POP EDI

反汇编分析__stdcall和__cdecl的异同

100115F5    5E              POP ESI

反汇编分析__stdcall和__cdecl的异同

100115F6    5B              POP EBX

反汇编分析__stdcall和__cdecl的异同

100115F7    8BE5            MOV ESP,EBP

反汇编分析__stdcall和__cdecl的异同

100115F9    5D              POP EBP

反汇编分析__stdcall和__cdecl的异同

100115FA    C2 0800         RETN 8

subtract方法:

反汇编分析__stdcall和__cdecl的异同

10011610    55              PUSH EBP

反汇编分析__stdcall和__cdecl的异同

10011611    8BEC            MOV EBP,ESP

反汇编分析__stdcall和__cdecl的异同

10011613    81EC C0000000   SUB ESP,0C0

反汇编分析__stdcall和__cdecl的异同

10011619    53              PUSH EBX

反汇编分析__stdcall和__cdecl的异同

1001161A    56              PUSH ESI

反汇编分析__stdcall和__cdecl的异同

1001161B    57              PUSH EDI

反汇编分析__stdcall和__cdecl的异同

1001161C    8DBD 40FFFFFF   LEA EDI,DWORD PTR SS:[EBP-C0]

反汇编分析__stdcall和__cdecl的异同

10011622    B9 30000000     MOV ECX,30

反汇编分析__stdcall和__cdecl的异同

10011627    B8 CCCCCCCC     MOV EAX,CCCCCCCC

反汇编分析__stdcall和__cdecl的异同

1001162C    F3:AB           REP STOS DWORD PTR ES:[EDI]

反汇编分析__stdcall和__cdecl的异同

1001162E    8B45 08         MOV EAX,DWORD PTR SS:[EBP+8]

反汇编分析__stdcall和__cdecl的异同

10011631    2B45 0C         SUB EAX,DWORD PTR SS:[EBP+C]

反汇编分析__stdcall和__cdecl的异同

10011634    5F              POP EDI

反汇编分析__stdcall和__cdecl的异同

10011635    5E              POP ESI

反汇编分析__stdcall和__cdecl的异同

10011636    5B              POP EBX

反汇编分析__stdcall和__cdecl的异同

10011637    8BE5            MOV ESP,EBP

反汇编分析__stdcall和__cdecl的异同

10011639    5D              POP EBP

反汇编分析__stdcall和__cdecl的异同

1001163A    C3              RETN

大家已经看到了,他们的唯一区别是:

使用__stdcall修饰的add方法,最后的RETN指令的操作数是8,而使用__cdecl修饰的subtract方法,最后的RETN指令没有操作数。

RETN指令的操作数为什么是8呢,原因也很简单,就是add方法有两个int参数,也就是说压栈的时候压入了两个字节,正好8位,RETN 8的意思应该是让栈顶指针ESP向后移动8位。

继续阅读