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

汇编和可执行文件

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

编译

        编译器在编译程序的时候,分为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)


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容