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 ...
随机推荐
- Redis学习-基础环境介绍(二)
1.通过VMware安装了Centos6.8系统 2.Reids安装过程,需要GCC环境 »通过下面命令,根据提示直接安装 1 yum install gcc 3.Redis选用的是3.2.4(建议使 ...
- LTE 测试文档(翻译)
Testing Documentation 翻译 (如有不当的地方,欢迎指正!) 1 概述 为了测试和验证 ns-3 LTE 模块,文档提供了几个 test suites (集成在 ns- ...
- DuiLib 源码分析之解析xml类CMarkup & CMarkupNode cpp文件
时隔5个月才有时间接着写未完成的实现部分,也是惭愧呀 选几个关机的函数来解析,一些get方法就忽略掉吧 CMarkupNode 与 CMarkUp 互为友元类,CMarkUp 实现解析,CMarkup ...
- 自定义view--实现滑动
1.重写 onInterceptTouchEvent() 拦截触摸事件 是由父控件向子控件传递 默认返回false 返回true,事件被当前的viewGroup进行处理,Touch事件不向下(子控件) ...
- c语言的continue
continue 是跳过此次循环的剩下部分,直接进入下个循环.
- APP敏捷测试,测试和开发并行!
测试和开发具有同等重要的作用,从一开始,测试和开发就是相向而行的.测试是开发团队的一支独立的.重要的支柱力量. 测试要具备独立性,独立分析业务需求,独立配置测试环境,独立编写测试脚本,独立开发测试工具 ...
- contiki-事件调度
事件驱动机制广泛应用于嵌入式系统,类似于中断机制,当有事件到来时(比如按键.数据到达),系统响应并处理该事件.相对于轮询机制,事件机制优势很明星,低功耗(系统处于休眠状态,当有事件到达时才被唤醒)和M ...
- ajax中使用post传值数组array
如果我们在data中想放入array的参数,根据在网上搜索的结果有如下方法,但是没有一个成功的……我还是贴出来,别人成功了,也许是我哪里不对,日后也许还有机会研究..在文章的最后贴出了转化为json的 ...
- 关于android的@TargetApi和@SuppressLint("NewApi")
看别人的代码好多地方用到了@TargetApi.以前一直不知道这个是什么意思.后面偶然看了下sdk.才有所明白. 其实这个东西就是在你使用了android Lint检查工具的时候,为了防止代码出现提示 ...
- Spring Bean
一.Spring的几大模块:Data access & Integration.Transcation.Instrumentation.Core Spring Container.Testin ...