zoukankan      html  css  js  c++  java
  • 反汇编分析__stdcall和__cdecl的异同

    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)
    {
        return a + b;
    }

    int __cdecl subtract(int a, int b)
    {
        return a - b;
    }


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

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

    add方法:

    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

  • 相关阅读:
    SQL_50题
    Java多线程之冰山一角
    概览
    Selector
    集群配置
    redis config
    分布式、集群
    redis相关技术总结
    redis scan扫描
    redis 单线程 多路io复用
  • 原文地址:https://www.cnblogs.com/findumars/p/6251018.html
Copyright © 2011-2022 走看看