linux内核学习之一 简单c语言反汇编
(我是第一次发技术博客的菜鸟,恳请大家指导!!)
一 由简单c程序生成汇编代码
首先给出本次我们要反汇编的简单c语言程序:(够简单吧~)

在linux环境中使用下面的命令条件编译:

生成汇编文件shiyan1.s:

shiyan1.s的部分代码截图:

全部粘贴出来如下:
.file "shiyan1.c"
.text
.globl g
.type g, @function
g:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset
.cfi_offset , -
movl %esp, %ebp
.cfi_def_cfa_register
movl (%ebp), %eax
addl $, %eax
popl %ebp
.cfi_restore
.cfi_def_cfa ,
ret
.cfi_endproc
.LFE0:
.size g, .-g
.globl f
.type f, @function
f:
.LFB1:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset
.cfi_offset , -
movl %esp, %ebp
.cfi_def_cfa_register
subl $, %esp
movl (%ebp), %eax
movl %eax, (%esp)
call g
leave
.cfi_restore
.cfi_def_cfa ,
ret
.cfi_endproc
.LFE1:
.size f, .-f
.globl main
.type main, @function
main:
.LFB2:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset
.cfi_offset , -
movl %esp, %ebp
.cfi_def_cfa_register
subl $, %esp
movl $, (%esp)
call f
addl $, %eax
leave
.cfi_restore
.cfi_def_cfa ,
ret
.cfi_endproc
.LFE2:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.GNU-stack,"",@progbits
去除链接信息的汇编代码:
g:
pushl %ebp
movl %esp, %ebp
movl (%ebp), %eax
addl $, %eax
popl %ebp
ret
f:
pushl %ebp
movl %esp, %ebp
subl $, %esp
movl (%ebp), %eax
movl %eax, (%esp)
call g
leave
ret
main:
pushl %ebp
movl %esp, %ebp
subl $, %esp
movl $, (%esp)
call f
addl $, %eax
leave
ret
二 汇编代码分析
前提:基于32位的系统,相关的寄存器也为32位
寄存器介绍:eax >> 累加器
ebp >> 堆栈基指针
esp >> 堆栈顶指针
eip >> 指向待执行的下一条指令,相当于pc
汇编指令介绍:


代码分析:我们都知道c语言代码是从main()函数开始执行的,汇编也不例外,找到main 的标志处,即第17行的位置。
| ebp(0) |
| 1 |
| eip(第23行) |
| ebp(1) |
| 1 |
| eip(第15行) |
| ebp(4) |
栈示意图
(栈向下增长,即在内存中由高地址向低地址生长,具体为什么还在探索,为了简化,从上向下依次编号0,1,2,3,4,5,6,7 ....实际对应内存中的32位地址)开始时为空栈,ebp,esp都是指向上面示意图中最上面,即ebp=0,esp=0,首先
pushl %ebp ;ebp的值入栈,如上图
movl %esp, %ebp ;ebp也指向esp的位置,即ebp=1
subl $4, %esp ;esp向下移动一格(寄存器为32位)
movl $1, (%esp) ;数值1 入栈
call f ;程序流程发生跳转,此时eip中保存的是下一条指令的地址(保证函数能够正确返回),为方便理解,上图中表示为第23行代码,下面即开始执行f子函数
pushl %ebp ;ebp的值(为1)入栈,此时栈顶指针esp=4
movl %esp, %ebp ;将esp的值赋给ebp,即ebp也指向4的位置
subl $4, %esp ;esp向下移动一个位置,为5
movl 8(%ebp), %eax ;变址寻址,取ebp指向的栈中退回两格的值,为1,赋给累加器eax
movl %eax, (%esp) ;将累加器eax中的值1入栈,如上图所示
call g ;程序流程再次发生跳转,此时eip中保存的是下一条指令的地址, 代码中的第15行,接下来执行子函数g中的代码
pushl %ebp ;将ebp的值入栈,此时ebp指向4的位置,即将4入栈,此时esp 为7 ,指向如上图所示
movl %esp, %ebp ;ebp也指向esp的位置
movl 8(%ebp), %eax ;变址寻址,取ebp指向的栈中退回两格的值,为1,赋给累加器eax
addl $2, %eax ;累加器中的值加2
popl %ebp ;ebp重新指向4的位置
ret ;eip指的位置(第15行代码),函数流程跳转,函数返回
leave ;esp也指向ebp的位置 ,指向4的位置,ebp出栈,ebp指向1的位置
ret ;函数返回,eip的值(第23代码在内存中的地址)出栈,程序流程发生跳转
leave
ret ;栈回到初始状态
上述分析过程相关的视频讲解链接已经附在文章最后。
三 总结
个人对计算机如何工作的理解:
计算机的工作离不开硬件和软件。软件支配硬件,要使计算机按照我们的意愿工作,首先我们先要将我们的意愿传达给计算机,这就是编程。但是计算机只能识别0和1,但是我们为了编程方便,设计的高级语言,这就需要一个翻译的工具,将高级语言翻译成计算机能够识别的机器语言(0和1),这就是编译器。编译器将一系列指令翻译成机器能识别的指令,cpu再从内存中取指令和数据,进行相应运算,再将结果回存,再取指,执行,回存。。。。
第一次发博客,水平有限,错误之处恳请指导!!
方龙伟
原创作品 转载请注明出处
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
linux内核学习之一 简单c语言反汇编的更多相关文章
- Linux内核分析——Linux内核学习总结
马悦+原创作品转载请注明出处+<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 Linux内核学习总结 一 ...
- Linux 内核学习的经典书籍及途径
from:http://www.zhihu.com/question/19606660 知乎 Linux 内核学习的经典书籍及途径?修改 修改 写补充说明 举报 添加评论 分享 • 邀请回答 ...
- 关于Linux内核学习的误区以及相关书籍介绍
http://www.hzlitai.com.cn/article/ARM9-article/system/1605.html 写给Linux内核新手-关于Linux内核学习的误区 先说句正经的:其实 ...
- linux内核学习之一:环境搭建--安装Debian7.3
本系列文章假设读者已对linux有一定的了解,其实学习linux内核不需要有很深的关于linux的知识,只需要了解以下内容:linux基础知识及基本shell命令:现代操作系统的基本概念:C语言和gc ...
- Linux 内核学习经验总结
Linux 内核学习经验总结 学习内核,每个人都有自己的学习方法,仁者见仁智者见智.以下是我在学习过程中总结出来的东西,对自身来说,我认为比较有效率,拿出来跟大家交流一下. 内核学习,一偏之见:疏漏难 ...
- 关于Linux内核学习的一点点总结
关于Linux内核学习的一点点总结 关键词:Linux, 操作系统,内核 博客列表 由反汇编C程序来理解计算机是如何工作的 通过分析一个简化版时间片轮转多道程序内核代码来认识操作系统中的进程调度 通过 ...
- Linux 内核 链表 的简单模拟(1)
第零章:扯扯淡 出一个有意思的题目:用一个宏定义FIND求一个结构体struct里某个变量相对struc的编移量,如 struct student { int a; //FIND(struct stu ...
- linux内核学习之二:编译内核
在linux内核学习系列的第一课中讲述了搭建学习环境的过程(http://www.cnblogs.com/xiongyuanxiong/p/3523306.html),环境搭好后,马上就进入到下一环节 ...
- Linux内核学习笔记-2.进程管理
原创文章,转载请注明:Linux内核学习笔记-2.进程管理) By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...
随机推荐
- 如何把 Callback 接口包装成 Promise 接口
最近一段时间一直在看Node.js,在开发过程中经常要调用一些异步接口,通常在接口的最后一个参数会传入一个回调函数,可以用来处理异常,非异常情况.大致模式如下: var fs = require(“f ...
- repeater重复器、地址栏传值、response
repeater重复器: <HeaderTemplate> <ItemTemplate> <AlternatingItemTemplate> <FooterT ...
- Linux时间设置及同步
Linux系统安装时选择的UTC时间是国际标准时间,而中国处于UTC+8时区,因此安装系统时不要选择UTC时区. 还有就是Linux有两个时钟: 1.Bios时钟及硬件时间 2.Kernel时钟及系统 ...
- Kafka 高可用设计
Kafka 高可用设计 2016-02-28 杜亦舒 Kafka在早期版本中,并不提供高可用机制,一旦某个Broker宕机,其上所有Partition都无法继续提供服务,甚至发生数据丢失对于分布式系统 ...
- HTML5 十大新特性(十)——Web Socket
webSocket是H5新加的一个协议,为了解决http协议的request.response一一对应和它自身的被动性,以及ajax轮询等问题.一方可以发送多条信息,连接不中断,永久连接,但也导致了服 ...
- <css篇>关于页面的绝对定位与相对定位,且支持页面各元素自适应
(哈哈,第一次写博客,简称处贴?主要记录下平时工作中遇到的问题及其解决方案,方便以后解决此类问题.) 话不多说,上代码看吧 代码有点乱,以后自己能看得懂就行咯 <body > <di ...
- 如何让同局域网的同事访问我电脑上的PHP网站和数据库
需求:想让公司同一局域网的同事电脑访问我的电脑里面的php项目. 条件:首先确认localhost正常访问你的本地项目 环境:我使用的是wampserver2.5集成环境 步骤: 1.增加新增监听端口 ...
- sql练习记录
三表关联如果字段为0则表示是散客卡 select a.shop_id as id,b.shop_name,a.balance,a.point,(IF(a.card_type_id<>0,c ...
- ef join 用法
var customers = DB.Customer.Join(DB.Commission, cst => cst.CommissionId, ...
- JS学习笔记--仿手机发送内容交互
学习JS笔记----记录上课中学习的知识点,分享下老师教的内容: 1.html内容 <div id="box"> <div id="message&qu ...