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

一  由简单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. php : 基础(3)

    运算符 算术运算符 基础: 符号有:+   -   *   /   % 说明: 他们都是针对数字进行的运算: 如果他们的两边有不是数字的数据,就会(自动)转换为数字: 其中取余运算(取模运算)%,它只 ...

  2. SPOJ 375 Query on a tree 树链剖分模板

    第一次写树剖~ #include<iostream> #include<cstring> #include<cstdio> #define L(u) u<&l ...

  3. 工具网站gallery

    jQuery各个版本齐全的api 在线编辑器codepen

  4. strcpy strlen memcpy等的函数实现

    #include <assert.h> #include <string.h> #include <stdlib.h> #include <stdio.h&g ...

  5. hostapd与wpa_supplicant

    hostapd与wpa_supplicant hostapd hostapd includes IEEE 802.11 access point management (authentication ...

  6. SQL Server Reporting Service(SSRS) 第四篇 SSRS 用法总结

    1. 如何让表头在每页显示(译) A. 打开高级模式:  在分组栏中点击Column Goups右侧的箭头选择高级模式; B. 找到第一个Static组 在Row Groups区域中(注意不是Colu ...

  7. Michael Schatz - 序列比对课程

    Michael Schatz - Cold Spring Harbor Laboratory 最近在研究 BWA mem 序列比对算法,直接去看论文,看不懂,论文就3页,太精简了,好多背景知识都不了解 ...

  8. [经验] Win7减肥攻略(删文件不删功能、简化优化系统不简优化性能)

    [经验] Win7减肥攻略(删文件不删功能.简化优化系统不简优化性能) ☆心梦无痕☆ 发表于 2014-1-24 11:15:04 https://www.itsk.com/thread-316471 ...

  9. mac系统使用帮助

    在linux下习惯使用ll.la.l等ls别名的童鞋到mac os可就郁闷了-- 其实只要在用户目录下建立一个脚本“.bash_profile”,并输入以下内容即可: alias ll='ls -al ...

  10. ADO.NET 访问数据库

    对数据库的访问时各种数据库应用程序开发的核心技术,.NET框架中提出的ADO.NET技术为应用程序的开发提供了一致的接口,增强了程序的可移植性和可扩展性. a:使用链接对象Connection连接数据 ...