zoukankan      html  css  js  c++  java
  • _stdcall 函数 debug/release汇编代码区别

    debug版本

    esp 栈顶指针

    ebp 存放堆栈指针

    空程序:
    int main()
    {
    00411360 push ebp ;压入ebp
    00411361 mov ebp,esp ;ebp = esp,保留esp,待函数调用完再恢复,因为函数调用中肯定会用到esp.
    00411363 sub esp,0C0h ;esp-=0C0h(192);为该函数留出临时存储区
    ;将其他指针或寄存器中的值入栈,以便在函数中使用这些寄存器。
    00411369 push ebx ;压入ebx
    0041136A push esi ;压入esi
    0041136B push edi ;压入edi
    0041136C lea edi,[ebp-0C0h] ;读入[ebp-0C0h]有效地址,即原esp-0C0h,正好是为该函数留出的临时存储区的最低位
    00411372 mov ecx,30h ;ecx = 30h(48),30h*4 = 0C0h
    00411377 mov eax,0CCCCCCCCh ;eax = 0CCCCCCCCh;
    0041137C rep stos dword ptr es:[edi] ;重复在es:[edi]存入30个;0CCCCCCCCh? Debug模式下把Stack上的变量初始化为0xcc,检查未初始化的问题
    return 0;
    0041137E xor eax,eax ;将eax清零,作为返回值
    }
    ;各指针出栈
    00411380 pop edi ;弹出edi
    00411381 pop esi ;弹出esi
    00411382 pop ebx ;弹出ebx
    00411383 mov esp,ebp ;esp复原
    00411385 pop ebp ;弹出ebp,也复原
    00411386 ret ;返回


    函数调用:

    int _tmain(int argc, _TCHAR* argv[])
    {
    同上理解, 保存现场
    004113D0 push ebp
    004113D1 mov ebp,esp
    004113D3 sub esp,0F0h ;一共留了0F0h(240)空间
    004113D9 push ebx
    004113DA push esi
    004113DB push edi
    004113DC lea edi,[ebp-0F0h]
    004113E2 mov ecx,3Ch ; ecx = 3C(60),3C*4 = 0F0h,
    004113E7 mov eax,0CCCCCCCCh
    004113EC rep stos dword ptr es:[edi]
    同上理解.
    int a = 1, b = 2, c = 3;
    定义a,b,c并存储在为函数留出的临时存储空间中.
    004113EE mov dword ptr [a],1
    004113F5 mov dword ptr [b],2
    004113FC mov dword ptr [c],3
    int d = Fun1(a, b, c);

    参数反向入栈
    00411403 mov eax,dword ptr [c]
    00411406 push eax
    00411407 mov ecx,dword ptr [b]
    0041140A push ecx
    0041140B mov edx,dword ptr [a]
    0041140E push edx
    调用Fun1
    0041140F call Fun1 (4111DBh) ;Call调用时将下一行命令的EIP压入堆栈
    恢复因为Fun1参数入栈改变的栈指针,因为Fun1有3个参数,一个整数4个字节,共0Ch(12)个字节
    00411414 add esp,0Ch
    00411417 mov dword ptr [d],eax
    将返回值保存在d中.
    return 0;
    返回值为0,让eax清零
    0041141A xor eax,eax

    }


    恢复现场
    0041141C pop edi
    0041141D pop esi
    0041141E pop ebx
    以下全为运行时ESP检查:
    先恢复因为为main预留空间而改变的栈指针
    0041141F add esp,0F0h
    00411425 cmp ebp,esp
    00411427 call @ILT+320(__RTC_CheckEsp) (411145h)
    正常时只需要以下两句就可以正常恢复esp,再出栈,又可以恢复ebp.
    0041142C mov esp,ebp
    0041142E pop ebp
    0041142F ret ;main返回

    release版本

    void fun1(int na, int na2,int na3,int na4)
    {
    sub esp,0E4h                            ;预留出空间栈                                
    mov eax,dword ptr [___security_cookie (11D3000h)]
    xor eax,esp
    mov dword ptr [esp+0E0h],eax          ;堆栈平衡检查

    xxxxxxxx

    }
    mov ecx,dword ptr [esp+0E0h]
     xor ecx,esp                               
     call __security_check_cookie (11D1056h)    ;堆栈平衡检查
     add esp,0E4h                                         ;还原esp
     ret

    release版本编译器对函数内的汇编代码做了一定的简化,少了ebp

  • 相关阅读:
    streamsets 集成 cratedb 测试
    streamsets k8s 部署试用
    streamsets rest api 转换 graphql
    StreamSets sdc rpc 测试
    StreamSets 相关文章
    StreamSets 多线程 Pipelines
    StreamSets SDC RPC Pipelines说明
    StreamSets 管理 SDC Edge上的pipeline
    StreamSets 部署 Pipelines 到 SDC Edge
    StreamSets 设计Edge pipeline
  • 原文地址:https://www.cnblogs.com/mayingkun/p/5615690.html
Copyright © 2011-2022 走看看