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

一  由简单c程序生成汇编代码

首先给出本次我们要反汇编的简单c语言程序:(够简单吧~)

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

生成汇编文件shiyan1.s:

shiyan1.s的部分代码截图:

全部粘贴出来如下:

1 .file "shiyan1.c"

2 .text3 .globl g4 .type g, @function5 g:6 .LFB0:7 .cfi_startproc8 pushl %ebp9 .cfi_def_cfa_offset 8

10 .cfi_offset 5, -8

11 movl %esp, %ebp12 .cfi_def_cfa_register 5

13 movl 8(%ebp), %eax14 addl $2, %eax15 popl %ebp16 .cfi_restore 5

17 .cfi_def_cfa 4, 4

18 ret19 .cfi_endproc20 .LFE0:21 .size g, .-g22 .globl f23 .type f, @function24 f:25 .LFB1:26 .cfi_startproc27 pushl %ebp28 .cfi_def_cfa_offset 8

29 .cfi_offset 5, -8

30 movl %esp, %ebp31 .cfi_def_cfa_register 5

32 subl $4, %esp33 movl 8(%ebp), %eax34 movl %eax, (%esp)35 call g36 leave37 .cfi_restore 5

38 .cfi_def_cfa 4, 4

39 ret40 .cfi_endproc41 .LFE1:42 .size f, .-f43 .globl main44 .type main, @function45 main:46 .LFB2:47 .cfi_startproc48 pushl %ebp49 .cfi_def_cfa_offset 8

50 .cfi_offset 5, -8

51 movl %esp, %ebp52 .cfi_def_cfa_register 5

53 subl $4, %esp54 movl $1, (%esp)55 call f56 addl $3, %eax57 leave58 .cfi_restore 5

59 .cfi_def_cfa 4, 4

60 ret61 .cfi_endproc62 .LFE2:63 .size main, .-main64 .ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"

65 .section .note.GNU-stack,"",@progbits

View Code

去除链接信息的汇编代码:

1 g:2 pushl %ebp3 movl %esp, %ebp4 movl 8(%ebp), %eax5 addl $2, %eax6 popl %ebp7 ret8 f:9 pushl %ebp10 movl %esp, %ebp11 subl $4, %esp12 movl 8(%ebp), %eax13 movl %eax, (%esp)14 call g15 leave16 ret17 main:18 pushl %ebp19 movl %esp, %ebp20 subl $4, %esp21 movl $1, (%esp)22 call f23 addl $3, %eax24 leave25 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 反汇编运行时代码段,linux内核学习之一 简单c语言反汇编(示例代码)相关推荐

  1. Linux系统运行时参数命令--Linux基础命令和工具

    目录 1 Linux基础命令和工具 1.1 grep搜索字符 1.2 find查找文件 1.3 ls显示文件 1.4 wc命令 1.5 ulimit用户资源 1.6 scp远程拷贝 1.7 dos2u ...

  2. php简单的购物车,利用PHP实现一个简单购物车的demo示例代码

    利用PHP实现一个简单购物车的demo示例代码 数据结构跟关于PHP写购物车大体差不多,这里站长主要就购物车的主要业务逻辑进行一下说明: 1.用户未登陆时只能浏览商品,不能将其加入购物车 2.当未登陆 ...

  3. android播放mp3功能,Android Studio实现简单音乐播放功能的示例代码

    项目要求 基于Broadcast,BroadcastReceiver等与广播相关的知识实现简单的音乐播放功能,包括音乐的播放.暂停.切换.进度选择.音量调整. 设计效果 (进度条时间刷新功能还没有实现 ...

  4. php简单验证码实例,php结合GD库简单实现验证码的示例代码

    前几日正好重温下GD库,来玩一下生成带有干扰素的验证码. 生成字母数字的图片验证码 首先需要看php.ini配置文件中有没有GD库,如果没有开启,请自行开启下,我用的小皮面板,基本现在都给你带上了. ...

  5. 用opengl编写一个简单的画图软件示例代码

    //用opengl编写一个简单的画图软件示例代码(存在闪烁问题) //本代码,抄写自一本教授opengl的书,可惜,里面的代码存在一些问题,导致不能正常显示,现在是增加了一些语句的代码 #includ ...

  6. LVGL库实现的简单实时时钟表盘示例代码

    LVGL库实现的简单实时时钟表盘示例代码: #include "lvgl.h" #include <time.h>static lv_obj_t * screen; s ...

  7. Linux Kernel运行时安全检测之LKRG-原理篇

    ​更多内核安全.eBPF分析和实践文章,请关注博客和公众号: CSDN博客:内核功守道 公众号: 内核功守道 背景介绍 虽然经常更新内核版本通常被认为是一种安全最佳实践,但由于各种原因,尤其是生产环境 ...

  8. linux选择运行的核数量,linux – 如何根据可用内核的数量选择最大负载阈值?

    负载在Linux上经常被误解. 在Linux上,它是运行或不间断睡眠状态中所有任务的度量. 请注意,这是任务,而不是进程.线程包含在此值中. 内核每五秒计算一次加载,并且是一个加权平均值.这是微小负载 ...

  9. linux 进程调度 运行队列 自旋锁,linux内核进程调度(自旋锁)

    2.1首先让我们了解,操作系统分为两类:一类是实时操作系统,一类是分时操作系统.它们的共同特点是都是多任务的 .多任务操作系统分为两类:非抢占式多任务和抢占式多任务. 非抢占式多任务,就是指进程不断的 ...

  10. Linux系统运行时参数命令

    文章目录 前言 一.Linux基础命令和工具 grep命令搜索字符 find命令查找文件 ls命令显示文件 wc命令计算字数 ulimit用户资源 curl http scp远程拷贝 dos2unix ...

最新文章

  1. WINCE6.0 Quarter VGA(QVGA) Resources组件
  2. 最近安装prestashop遇到莫名其妙的问题。突然毛瑟顿开了,create default language就出现错误...
  3. jenkins 新手入门安装失败_树莓派安装jenkins,安安静静做个持续集成打包机
  4. 不能将参数转化为lparam_如何将管理需求转化为信息化方案
  5. 阿里云服务器ECS数据盘的自动挂载解决方案
  6. Idea的JShell Console
  7. mac html乱码,Mac 复制网页乱码
  8. 同步时间服务器修改同步间隔,如何更改Windows 10时间同步间隔
  9. 创建线程-学到了4种方法
  10. 单链表的逆置(递归和非递归)
  11. 夏时制英国和中国的时差是多少?伦敦与北京时差是多少?
  12. 中国历史上5个谣言,单是第1条就骗了不少人!
  13. 如何从零开始学python_《如》字意思读音、组词解释及笔画数 - 新华字典 - 911查询...
  14. 漂亮特殊字体可复制_特殊字体生成器 漂亮特殊字体可复制
  15. 昭和女神异闻录——中山美穗
  16. 关于在校大学生的Edu教育邮箱能够薅到的羊毛
  17. 教你搭建个人/企业私有云盘-seafile
  18. 计算机操作系统-中断
  19. MySQL---数据库从入门走向大神系列(十)-Connection对象池、装饰模式与动态代理模式
  20. 海波专栏(水晶报表)

热门文章

  1. 小D课堂 - 新版本微服务springcloud+Docker教程_6-05 高级篇幅之高并发情况下
  2. 阶段3 2.Spring_08.面向切面编程 AOP_7 通用化切入点表达式
  3. 阶段3 2.Spring_07.银行转账案例_2 案例中添加转账方法并演示事务问题
  4. Trait这个类的特性
  5. leetcode 979. 在二叉树中分配硬币
  6. CF125E MST Company
  7. ajax跨域原理以及jsonp使用
  8. vs 2012/2013 等工具中,使用正则表达式,查找、替换
  9. Python 之图片对比
  10. 《学习之道》第十七章保持平静