署名信息

郭春阳 原创作品转载请注明出处 :《Linux内核分析》MOOC课程 http://mooc.study.163.com/course/USTC-1000029000

C源码

这里为了防止重复,修改了部分源码

int g(int x)
{
return x + 99;
} int f(int x)
{
return g(x);
} int main(void)
{
return f(22) + 36;
}

运行 gcc -S -o foo.s -m32 foo.c后,生成的汇编代码为:

g:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
addl $99, %eax
popl %ebp
ret
f:
pushl %ebp
movl %esp, %ebp
pushl 8(%ebp)
call g
addl $4, %esp
leave
ret
main:
pushl %ebp
movl %esp, %ebp
pushl $22
call f
addl $4, %esp
addl $36, %eax
leave
ret

分析代码运行过程

首先进入main函数:

`pushl	 %ebp, movl %esp, %ebp`两行代码,将ebp压入栈,
然后esp的值赋给ebp,这里esp的值先减4,ebp指向与esp相同的位置
以上指令相当于enter,进入了一个新的函数调用栈
将22压入栈(这里其实是定义接下来调用的f的形参int x,并赋值)
调用f,这里先保存eip(PC计数器)的值入栈,esp的值-4,然后将f的地址赋给eip

进入f函数:

执行enter的两条指令,进入新的函数调用栈(同上)
将ebp向前8个字节位置的值(main中压栈的22)压栈,esp-4
这里是定义g的形参并赋值
调用g,eip先压栈,然后eip变为g的地址

进入g函数:

首先执行enter的两条指令,进入新的调用栈(同上)
`movl 8(%ebp), %eax` 首先寻址,将f中压栈的数(也就是g的形参x),赋给eax
`addl $99, %eax` eax中得值+99,对应C语句 x + 99
`popl %ebp` 这里因为g中没有开辟新的栈空间(esp的值没有变化),所以这句和leave语句等价
执行完,这一句,ebp恢复到之前的值(f中得状态)
执行ret,其实是执行popl eip,将栈中保存的eip的值,赋给eip
此时ebp、esp和eip均恢复到调用f中得状态
退出g,返回值保存在eax中

回到f函数:

`addl    $4, %esp`  esp+4,因为前面进行了pushl开辟新的变量,所以这里需要丢弃栈顶
之后执行leave 和 ret,恢复esp、ebp、eip的值,同上
f仅仅返回g的返回值,这里不改动eax,里面保存着g的返回值

回到main函数:

`addl    $4, %esp`丢弃栈顶,原因是上面进行push,定义了新的变量
` addl $36, %eax` f(22)的返回值+36,相当于C中得 f(22) + 36
main函数leave ret 返回上一层
gcc中应该为__libc_start_main,它可以接收到main的返回值,在eax中

注意点

1.C中的函数,是先定义形参并赋值,然后才进入该函数代码
2.函数调用中占用的栈空间,不仅仅包括局部变量,还包括22这种常量
3.每次函数调用,都执行enter,这条指令的效果相当于开辟了一个新的空栈
4.call调用函数时,eip保存的是call的下一条指令

博客截图

实验环境是在Ubuntu 14.10 32bit,在mac OS X上远程登录

对计算机工作流程的认识

图灵机可以执行某些特定操作
通用图灵机可以执行传给它的指令
现在计算机采用冯诺依曼体系结构,将程序和数据均存储在内存中,只需要程序员编写计算机可以识别的代码即可,计算机会将这些代码编译为可执行的指令。

分析一个C语言程序生成的汇编代码-《Linux内核分析》Week1作业的更多相关文章

  1. Linux内核分析第六周学习笔记——分析Linux内核创建一个新进程的过程

    Linux内核分析第六周学习笔记--分析Linux内核创建一个新进程的过程 zl + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...

  2. linux内核分析综合总结

    linux内核分析综合总结 zl + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 Linux内核分析 ...

  3. Linux内核分析(七)----并发与竞态

    原文:Linux内核分析(七)----并发与竞态 Linux内核分析(七) 这两天家里的事好多,我们今天继续接着上一次的内容学习,上次我们完善了字符设备控制方法,并深入分析了系统调用的实质,今天我们主 ...

  4. Linux内核分析(五)----字符设备驱动实现

    原文:Linux内核分析(五)----字符设备驱动实现 Linux内核分析(五) 昨天我们对linux内核的子系统进行简单的认识,今天我们正式进入驱动的开发,我们今后的学习为了避免大家没有硬件的缺陷, ...

  5. 简单C程序生成的汇编代码分析

    首先给出完整的C代码: int g(int x) { ; } int f(int x) { return g(x); } int main(void) { )+; } 使用命令:gcc –S –o h ...

  6. 《linux内核分析》作业一:分析汇编代码

    通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的(王海宁) 姓名:王海宁                             学号:20135103 课程:<Linux内核分析& ...

  7. linux内核分析作业:以一简单C程序为例,分析汇编代码理解计算机如何工作

    一.实验 使用gcc –S –o main.s main.c -m32 命令编译成汇编代码,如下代码中的数字请自行修改以防与他人雷同 int g(int x) { return x + 3; } in ...

  8. linux内核分析作业4:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

    系统调用:库函数封装了系统调用,通过库函数和系统调用打交道 用户态:低级别执行状态,代码的掌控范围会受到限制. 内核态:高执行级别,代码可移植性特权指令,访问任意物理地址 为什么划分级别:如果全部特权 ...

  9. Linux内核分析—完成一个简单的时间片轮转多道程序内核代码

    ---恢复内容开始--- 20135125陈智威 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-10 ...

随机推荐

  1. Linux系统下 解决Qt5无法连接MySQL数据库的方法

    Linux平台下解决Qt5连接mysql数据库的问题:输入sudo apt-get install libqt5sql5-mysql解决,这种方法只能解决Qt是用sudo apt-get instal ...

  2. ASP.NET 创建网站地图

    很多个人站长会使用工具来生成自己网站的站点地图,这样做的缺点在于网站的 sitemap 不能及时的得到更新.当我们发表了一篇新文章时,应该对网站的地图进行更新,并通知搜索引擎网站地图已经发生了改变! ...

  3. jQuery easyui treegrid无法传参到后台bugger一记

    $("#lTreegrid").treegrid("options").queryParams={id:123456,name:"Hai he&quo ...

  4. Web服务器Nginx多方位优化策略

    标签:性能 Web 架构 Nginx 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://dongsong.blog.51cto.co ...

  5. jquery 让select元素中的某个option被选中

    jquery 操作select 取值,设置选中值 博客分类: javaScript selecttextvalue取值设置选中值 比如 <select class="type" ...

  6. Oracle 截取、查找字符函数(持续更新)

    整理一些常用的截取.查找字符函数: 1.查找某一个字符串中某一个字符(串)出现的次数 SELECT LENGTH(REGEXP_REPLACE(REPLACE('anne<br>lily& ...

  7. windows server 2008 - 创建域和本机用户

    /* * ===================================================================================== * Filenam ...

  8. sql语句练习50题

    Student(Sid,Sname,Sage,Ssex) 学生表 Course(Cid,Cname,Tid) 课程表 SC(Sid,Cid,score) 成绩表 Teacher(Tid,Tname) ...

  9. 【温故Delphi】之编译与链接(转)

    本文基本转自“Delphi编译/链接过程” @瓢虫Monster,向瓢虫君学习,:) 下图展示了Delphi是怎样编译源文件,并把它们链接起来,最终形成可执行文件的. 当Delphi编译项目(Proj ...

  10. BFS 或 同余模定理(poj 1426)

    题目:Find The Multiple 题意:求给出的数的倍数,该倍数是只由 1与 0构成的10进制数. 思路:nonzero multiple  非零倍数  啊. 英语弱到爆炸,理解不了题意... ...