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

  • 相关阅读:
    java static关键字的四种用法
    修改Intellij IDEA模板注解@author变量user内容
    iIDEA: 运行Scala代码右键没有Run选项
    idea 无法创建Scala class 选项解决办法汇总
    scala之idea下如何新建scala工程
    scala之windows环境安装与配置
    @RestController注解
    @component的作用详细介绍
    springboot 日期参数前后台转换问题
    MySQL数据库硬件选择
  • 原文地址:https://www.cnblogs.com/mayingkun/p/5615690.html
Copyright © 2011-2022 走看看