(我是第一次发技术博客的菜鸟,恳请大家指导!!)

一  由简单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语言反汇编的更多相关文章

  1. Linux内核分析——Linux内核学习总结

    马悦+原创作品转载请注明出处+<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 Linux内核学习总结 一 ...

  2. Linux 内核学习的经典书籍及途径

    from:http://www.zhihu.com/question/19606660 知乎 Linux 内核学习的经典书籍及途径?修改 修改 写补充说明 举报   添加评论 分享 • 邀请回答   ...

  3. 关于Linux内核学习的误区以及相关书籍介绍

    http://www.hzlitai.com.cn/article/ARM9-article/system/1605.html 写给Linux内核新手-关于Linux内核学习的误区 先说句正经的:其实 ...

  4. linux内核学习之一:环境搭建--安装Debian7.3

    本系列文章假设读者已对linux有一定的了解,其实学习linux内核不需要有很深的关于linux的知识,只需要了解以下内容:linux基础知识及基本shell命令:现代操作系统的基本概念:C语言和gc ...

  5. Linux 内核学习经验总结

    Linux 内核学习经验总结 学习内核,每个人都有自己的学习方法,仁者见仁智者见智.以下是我在学习过程中总结出来的东西,对自身来说,我认为比较有效率,拿出来跟大家交流一下. 内核学习,一偏之见:疏漏难 ...

  6. 关于Linux内核学习的一点点总结

    关于Linux内核学习的一点点总结 关键词:Linux, 操作系统,内核 博客列表 由反汇编C程序来理解计算机是如何工作的 通过分析一个简化版时间片轮转多道程序内核代码来认识操作系统中的进程调度 通过 ...

  7. Linux 内核 链表 的简单模拟(1)

    第零章:扯扯淡 出一个有意思的题目:用一个宏定义FIND求一个结构体struct里某个变量相对struc的编移量,如 struct student { int a; //FIND(struct stu ...

  8. linux内核学习之二:编译内核

    在linux内核学习系列的第一课中讲述了搭建学习环境的过程(http://www.cnblogs.com/xiongyuanxiong/p/3523306.html),环境搭好后,马上就进入到下一环节 ...

  9. Linux内核学习笔记-2.进程管理

    原创文章,转载请注明:Linux内核学习笔记-2.进程管理) By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...

随机推荐

  1. 汇编语言写出的helloworld运行过程

    一:首先说一点,这篇文章建立在懂一点汇编的基础上,有几个简单的命令,说以下: 1:-r命令 -r 查看寄存器 -r 寄存器 (如 -r AX) 修改寄存器的值: 2:-d命令 -d 地址:xxxx:x ...

  2. 关于xml配置实现AOP的小知识

    除了前面介绍的基于JDK1.5的注解方式来定义切面,切入点和增强处理外,Spring AOP也允许直接使用XML配置文件来管理它们.在JDK1.5之前,只能使用配置文件的方式来管理,在Spring2. ...

  3. C++ STL vector容器学习

    STL(Standard Template Library)标准模板库是C++最重要的组成部分,它提供了一组表示容器.迭代器.函数对象和算法的模板.其中容器是存储类型相同的数据的结构(如vector, ...

  4. Evolutionary Computing: Assignments

    Assignment 1: TSP Travel Salesman Problem Assignment 2: TTP Travel Thief Problem The goal is to find ...

  5. matlab 视频转换到图像并保存

    图像处理中像Adas.车辆检测等都需要采用视频文件比较好处理一点,利用帧差法.背景减法.光流法等,那么将视频文件转换到图像文件怎么做呢?话不多说,见代码一目了然: %================= ...

  6. 自动生成build.xml文件

    使用Eclipse 自动生成 Ant的Build.xml 配置文件,选择要生成Build.xml文件的项目,鼠标右键, Export-> General -> Ant Buildfiles ...

  7. Oracle笔记二

    一.数据库语言分类  二.DML之数据插入 把一个表中的数据查询出来插入另外一个表中. create table student(id number,name varchar2(20),age num ...

  8. Matrix

    记载: Matrix Matrix是Android 提供的一个矩阵工具类,位于"android.graphics.Matrix"包下,它本身不能对图像或View进行变换, 但它可以 ...

  9. 【转】Centos升级Python 2.7.12并安装pip、ipython

    Centos系统一般默认就安装有Python2.6.6版本,不少软件需要2.7以上的,通过包管理工具安装不了最新的版本,通过源码编译可以方便安装指定版本,只需要把下面版本的数字换成你想要的版本号. 1 ...

  10. 重温Javascript第一章

    一.script标签 script标签有6个属性,其中一个废弃,五个可选. 按照传统的写法,<script>的标签都是放在<head>元素中,但是在<head>中包 ...