分享
 
 
 

C程序汇编运行模式简析

王朝学院·作者佚名  2016-05-26
窄屏简体版  字體: |||超大  

C程序汇编运行模式简析SJTUBEAR 原创作品转载请注明出处 /《linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

1. 汇编 在修习LINUX内核这门课的初始阶段,首先需要掌握的就是汇编以及汇编程序对于堆栈的操作。

下面我们就来分析一下一个简单地C程序是如何被汇编程序所表达的!

2. 得到汇编代码 首先,我们写一个简单地C程序,命名为exp1.c:

1 #include <stdio.h> 2 3 int g(int x) 4 { 5 return x+3; 6 } 7 8 int f(x) 9 {10 return g(x);11 }12 13 int main()14 {15 return f(8)+1; 16 }

程序非常的简单,我们此时再通过编译指令将其编译为汇编程序:

1 gcc –S –o main.s main.c -m32

这样我们就得到了这个简单C程序的汇编代码:

1 .file "exp1.c" 2 .text 3 .globl g 4 .type g, @function 5 g: 6 .LFB0: 7 .cfi_startPRoc 8 pushl %ebp 9 .cfi_def_cfa_offset 810 .cfi_offset 5, -811 movl %esp, %ebp12 .cfi_def_cfa_register 513 movl 8(%ebp), %eax14 addl $3, %eax15 popl %ebp16 .cfi_def_cfa 4, 417 .cfi_restore 518 ret19 .cfi_endproc20 .LFE0:21 .size g, .-g22 .globl f23 .type f, @function24 f:25 .LFB1:26 .cfi_startproc27 pushl %ebp28 .cfi_def_cfa_offset 829 .cfi_offset 5, -830 movl %esp, %ebp31 .cfi_def_cfa_register 532 subl $4, %esp33 movl 8(%ebp), %eax34 movl %eax, (%esp)35 call g36 leave37 .cfi_restore 538 .cfi_def_cfa 4, 439 ret40 .cfi_endproc41 .LFE1:42 .size f, .-f43 .globl main44 .type main, @function45 main:46 .LFB2:47 .cfi_startproc48 pushl %ebp49 .cfi_def_cfa_offset 850 .cfi_offset 5, -851 movl %esp, %ebp52 .cfi_def_cfa_register 553 subl $4, %esp54 movl $8, (%esp)55 call f56 addl $1, %eax57 leave58 .cfi_restore 559 .cfi_def_cfa 4, 460 ret61 .cfi_endproc62 .LFE2:63 .size main, .-main64 .ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"65 .section .note.GNU-stack,"",@progbits

3.汇编代码分析 汇编出的代码,多了很多辅助信息,为了能够更好地看清主干,我们删减一下:

1 g: 2 pushl %ebp //保存现场,将父函数的栈底寄存器存入当前程序栈中 3 movl %esp, %ebp //构建当前函数堆栈 4 movl 8(%ebp), %eax //从父函数堆栈中取得参数,存入ax寄存器 5 addl $3, %eax //完成+3操作 6 popl %ebp //恢复原父函数堆栈 7 ret //pop出原Eip地址,恢复执行 8 f: 9 pushl %ebp //保存现场,将父函数的栈底寄存器存入当前程序栈中10 movl %esp, %ebp //构建当前函数堆栈11 subl $4, %esp //栈顶加一,用以储存变量传递给g函数12 movl 8(%ebp), %eax //取得参数13 movl %eax, (%esp) //将参数传入变量位置14 call g //调用g15 leave //清楚局部变量空间16 ret //返回17 main:18 pushl %ebp19 movl %esp, %ebp20 subl $4, %esp //空出局部变量空间21 movl $8, (%esp) //为变量赋值22 call f //调用f23 addl $1, %eax //完成+1操作24 leave //清理局部变量25 ret //返回

我们对f函数进行详细的分析:

1. 首先进行enter指令:

此时,ebp当前所指向的位置存入栈顶,并且将ebp重定向指向esp:

2.栈顶加一并存入变量值:

3.调用g

4.从g返回后,返回值储存在AX寄存器中,不用操作,调用leave,清理变量

5.最后ret,同时EIP被读出恢复到原位置继续执行,返回值在AX中传递给调用函数

3.个人的一点感悟: 程序的调用就是这样嵌套的执行下去,每个函数都有自己的堆栈用以储存当前变量以及环境值,并通过将父函数的EBP放入栈底用以恢复环境。

同时EIP存入父栈栈顶,便于恢复到原节点处继续执行。

这样,就可以有规律的一直嵌套下去。

如果使用递归函数,就是一个码堆栈的过程,知道最顶部的堆栈返回,函数就像多米诺骨牌一样收回所有的堆栈。

这也是递归函数占用空间比较多的原因之一。如果没有很好地退出机制,有可能内存溢出。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有