美文网首页
06_函数调用过程(计算机科学)

06_函数调用过程(计算机科学)

作者: yishurensheng | 来源:发表于2017-11-25 17:37 被阅读0次

    汇编和可执行文件

            前面我们已经知道,汇编约等于机器码。源代码通过编译器(也是一个软件)进行编译,得到机器码。以后我们统一用汇编代替机器码。

    编译

            编译器在编译程序的时候,分为Debug版本和Release版本。编译器不会对Debug版本的程序进行优化,而编译器会对Release版本的程序进行优化。下面是在反汇编的情况下对Debug版本和Release版本进行一下比较。
    源代码如下所示:

    int main()
    {
        int iCount = 10;
        double dStep = 0.123;
    
        return 0;
    }
    

    对应的Debug版本汇编代码如下所示:

    int main()
    {
    000F1A50  push        ebp  
    000F1A51  mov         ebp,esp  
    000F1A53  sub         esp,0DCh  
    000F1A59  push        ebx  
    000F1A5A  push        esi  
    000F1A5B  push        edi  
    000F1A5C  lea         edi,[ebp-0DCh]  
    000F1A62  mov         ecx,37h  
    000F1A67  mov         eax,0CCCCCCCCh  
    000F1A6C  rep stos    dword ptr es:[edi]  
        int iCount = 10;
    000F1A6E  mov         dword ptr [iCount],0Ah  
        double dStep = 0.123;
    000F1A75  movsd       xmm0,mmword ptr [__real@3fbf7ced916872b0 (0F6CB0h)]  
    000F1A7D  movsd       mmword ptr [dStep],xmm0  
    
        return 0;
    000F1A82  xor         eax,eax  
    }
    

    对应的Release版本汇编代码如下所示:

        int iCount = 10;
        double dStep = 0.123;
    
        return 0;
    008B1000  xor         eax,eax  
    }
    

    从上面汇编代码的结果可以看出,Debug版本的汇编代码会将iCount和dStep这两个变量转换成汇编代码,而Release版本的汇编代码就会将iCount和dStep这两个变量省略掉,也就是会对源代码做一些优化。并且Debug版本生成的可执行文件的大小(本程序为35.5KB)相对于Release版本的可执行程序的大小(本程序为9.00KB)也要大很多。所以我们建议在以后调试程序的时候,最好使用Debug版本进行编译,这样编译器就不会帮我们优化源代码。

    链接

    整个内存可以分为四个区域,分别为:

    • 栈区
      栈区具有可增长性。VS为每个线程默认分配1024KB大小的栈空间,如果在栈上分配的空间超过1024KB,就会产生栈溢出的错误。
      栈空间使用的大小由两个寄存器来决定,分别是栈底指针和栈顶指针,栈空间中的变量在增加时,栈顶指针就会一点一点的向上移动,到最后如果这些变量都已经没有用了,栈顶指针就会指向栈底指针,表示原来的那些变量已经是垃圾数据了。
      如果栈空间上存在函数调用过程(栈的回溯功能),那么还会有保存栈底指针的变量,具体的这里就先不做详细说明了。
    • 堆区
    • 代码区
    • 常量区

    这样划分的目的是为了我们编写的程序更加安全。这样划分区域后,就可以将代码区和常量区设置为只读属性,从而达到程序中的代码以及用到的一些常量就不会被意外的修改,提高了程序在运行期间的安全性。

    汇编代码

    汇编指令:
    push代表压栈的操作
    pop代表出栈的操作
    ebp栈底指针寄存器
    esp栈顶指针寄存器
    eip程序计数器
    efl 标志寄存器

    下面一般作为通用寄存器:
    eax 累加寄存器
    edi 源寄存器
    esi 基址寄存器

    下面是在main函数中只执行一句printf("Hello World!")语句时,ebp和esp的一系列值。

    EBP             ESP             OPRATION
    009DFA30        009DF964    
                    009DF960        offset string "Hello World!" (0A06BCCh)
                    009DF95C        00A02093  call        _printf (0A01370h)
                    009DF958        00A02900  push        ebp
    009DF958                        00A02901  mov         ebp,esp
                    009DF880        00A02903  sub         esp,0D8h
                    009DF87C        00A02909  push        ebx
                    009DF878        00A0290A  push        esi
                    009DF874        00A0290B  push        edi
                    009DF870        00A0291E  call        __vcrt_va_start_verify_argument_type<char const * const> (0A011CCh)
                    009DF874        00A011CC  jmp         __vcrt_va_start_verify_argument_type<char const * const> (0A02170h)
                    009DF870        00A0292C  push        eax
                    009DF86C        00A0292D  push        0
                    009DF868        00A02932  push        ecx
                    009DF864        00A02935  push        1
                    009DF860        00A02937  call        dword ptr [__imp____acrt_iob_func (0A0A16Ch)]
                    009DF85C        53A6D362  push        ebp
                    009DF85C        53A6D363  mov         ebp,esp
    009DF958        009DF860        53A6D36E  pop         ebp
                    009DF864        53A6D36F  ret
                    009DF868        00A0293D  add         esp,4
                    009DF864        00A02942  call        __RTC_CheckEsp (0A01113h)
                    009DF868        
                    009DF864        00A02947  push        eax
                    009DF860        00A02948  call        __vfprintf_l (0A0136Bh)
                    009DF85C        00A019C0  push        ebp
    009DF85C                        00A019C1  mov         ebp,esp
                    009DF79C        00A019C3  sub         esp,0C0h
                    009DF798        00A019C9  push        ebx
                    009DF794        00A019CA  push        esi
                    009DF790        00A019CB  push        edi
                    009DF78C        00A019E3  push        eax
                    009DF788        00A019E7  push        ecx
                    009DF784        00A019EB  push        edx
                    009DF780        00A019EF  push        eax
                    009DF77C        00A019F0  call        ___local_stdio_printf_options (0A01339h)
                    009DF780        00A01339  jmp         __local_stdio_printf_options (0A02AB0h)
                    009DF77C        00A019F8  push        ecx
                    009DF778        00A019FB  push        edx
                    009DF774        00A019FC  call        dword ptr [__imp____stdio_common_vfprintf (0A0A168h)]
                    009DF770        53A67FF2  push        ebp
    009DF770                        53A67FF3  mov         ebp,esp
                    009DF76C        53A67FF8  push        eax
                    009DF768        53A67FFC  push        ecx
                    009DF764        53A68000  push        edx
                    009DF760        53A68004  push        eax
                    009DF75C        53A68008  push        ecx
                    009DF758        53A6800C  push        edx
                    009DF754        53A6800D  call        53A4CA90
                    009DF750        53A4CA92  push        ebp
    009DF750                        53A4CA93  mov         ebp,esp
                    009DF72C        53A4CA95  sub         esp,24h
                    009DF728        53A4CB8A  push        ecx
                    009DF724        53A4CB8E  push        edx
                    009DF720        53A4CB92  push        eax
                    009DF71C        53A4CB96  push        ecx
                    009DF718        53A4CB9A  push        edx
                    009DF714        53A4CB9E  call        53A20590
                    009DF710        53A20592  push        ebp
    009DF710                        53A20593  mov         ebp,esp
                    009DF70C        53A20595  push        ecx
                    009DF710        53A205C8  mov         esp,ebp
    009DF750        009DF714        53A205CA  pop         ebp
                    009DF72C        ret
                    009DF728        53A4CBA3  push        eax
                    009DF724        53A4CBA7  push        eax
                    009DF72C        53A4CBAD  add         esp,8
                    009DF750        53A4CBB0  mov         esp,ebp
    009DF770        009DF754        53A4CBB2  pop         ebp
                    009DF758        53A4CBB3  ret
                    009DF770        53A68012  add         esp,18h
    009DF85C        009DF774        53A68015  pop         ebp
                    009DF778        53A68016  ret
                    009DF790        00A01A02  add         esp,18h
                    009DF794        00A01A0C  pop         edi
                    009DF798        00A01A0D  pop         esi
                    009DF79C        00A01A0E  pop         ebx
                    009DF85C        00A01A0F  add         esp,0C0h
                    009DF85C        00A01A17  call        __RTC_CheckEsp (0A01113h)
    009DF958        009DF860        00A01A1E  pop         ebp
                    009DF864        00A01A1F  ret
                    009DF874        00A0294D  add         esp,10h
                    009DF878        00A0295D  pop         edi
                    009DF87C        00A0295E  pop         esi
                    009DF880        00A0295F  pop         ebx
                    009DF958        00A02960  add         esp,0D8h
                    009DF958        00A02968  call        __RTC_CheckEsp (0A01113h)
    009DF958        009DF958        00A0296D  mov         esp,ebp
    009DFA30        009DF95C        00A0296F  pop         ebp
                    009DF960        00A02970  ret
                    009DF964        00A02098  add         esp,4
                    009DF968        00A0209D  pop         edi
                    009DF96C        00A0209E  pop         esi
                    009DF970        00A0209F  pop         ebx
                    009DFA30        00A020A0  add         esp,0C0h
    009DFA44        009DFA34        00A020AF  pop         ebp
                    009DFA38        00A020B0  ret
    009DFA44                        00A0214E  add         esp,0Ch
    009DFA9C        009DFA48        00A02151  pop         ebp
                    009DFA4C        00A02152  ret
                    009DFA48        00A01FC2  push        ecx
                                    00A01FC3  call        _exit (0A012CBh)
    
    
    

    相关文章

      网友评论

          本文标题:06_函数调用过程(计算机科学)

          本文链接:https://www.haomeiwen.com/subject/zbscbxtx.html