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

2017-11-25  本文已影响0人  yishurensheng

汇编和可执行文件

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

编译

        编译器在编译程序的时候,分为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版本进行编译,这样编译器就不会帮我们优化源代码。

链接

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

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

汇编代码

汇编指令:
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)


上一篇下一篇

猜你喜欢

热点阅读