通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的

于佳心 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

计算机是如何工作的?

计算机的工作的基础冯诺依曼体系结构,即存储程序计算机。

这里涉及到两个重要的接口,一个是API,程序员与计算机的接口,另一个是ABI,程序与CPU的接口。

程序员通过编程语言下达指令,指令则通过汇编被翻译成计算机语言,使计算机能够明白你的意思,进而执行。

汇编语言中的指令有好多种,大多数指令可以直接访问内存。

下面就是一个将C代码编译成汇编代码的具体操作过程

这个程序的返回值为21

检验一下,可以运行(没有输出)

输入给出的语句编译成汇编代码,生成.s文件

长长的汇编代码出炉

据说前面带“.”的语句表示链接

☝☝☝☝☝

精简版汇编代码

可见这个程序分为三部分:主函数,子函数f,子函数的子函数g

在程序开始运行之前,系统中有一个空堆栈,指向栈底的ebp和指向栈顶的esp都指向0的位置,eip存储cpu要读取的指令的地址,每运行一步它就自动+1,eax是返回值。

需要注意的是,下面图片中的图片0,1,2,3...并不是真正的地址值,只是为了方便才这样写,按理说应该是以4为单位向下逐级递减的,比如2016,2012,2008...

程序从main开始运行:

       

执行到call f这一步时,eip指向了f,接下来将从f开始运行:

    

  

call g之后开始运行g中的指令:

    

ret就相当于popl %eip,eip跳转到了15,开始执行f中未进行的指令,leave可拆分成如下图中的两步(指令后面的 l 忘记写了。。。)

  

eip跳转到了23,执行main中未执行的指令(最后一个ret可能涉及到这个程序之外的内容,不予考虑)

  

程序运行完毕,返回值正确

堆栈的功能是暂时存放数据和地址,观察图片我发现,堆栈的形态先是不断的向下伸长,长到一定程度就往回收缩,最后的形态与它的原始形态相同。

总结

通过这次试验,我更加深入的理解了计算机是如何工作的。首先我们要把一段程序送给计算机(也有可能是计算机自带的程序),我们要明确的告诉计算机从哪里取需要的数值,如何操作,将操作后得数值放到哪里。然后,计算机会按照程序的顺序一步一步将指令取出,翻译成自己能懂的语言,再进行操作,运行完一条指令,再取下一条指令,这便是冯诺依曼原理。寄存器在执行指令过程中起到了很大的作用。操作中需要用到的数据都存储在堆栈里,通过两个地址寄存器在适当的时候调用。eip则控制程序的执行顺序,何时应该顺序执行,何时应该跳转。eax用于保存返回值。

虽然一步一步画图分析很麻烦,但是分析完还是很有成就感的,虽然看视频觉得自己已经很懂了,真正分析起来还是会出现问题,会无从下手,又要翻出视频来求助,完整的分析一遍后发现这才是真正记住了,果然记忆光靠看不行,还要靠实践。

假期的最后几天忽然有了学习任务,好在并不是很难,学到的内容大多都接触过,但是由于记忆力太差,和新学的没什么区别,以前学的时候就没怎么弄懂,现在终于弄懂了。

希望大家假期最后几天都玩得开心~

Linux内核分析作业 NO.1的更多相关文章

  1. linux内核分析作业8:理解进程调度时机跟踪分析进程调度与进程切换的过程

    1. 实验目的 选择一个系统调用(13号系统调用time除外),系统调用列表,使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用 分析汇编代码调用系统调用的工作过程,特别是参数的传递的方 ...

  2. Linux内核分析作业7:Linux内核如何装载和启动一个可执行程序

            1.可执行文件的格式 在 Linux 平台下主要有以下三种可执行文件格式: 1.a.out(assembler and link editor output 汇编器和链接编辑器的输出) ...

  3. linux内核分析作业6:分析Linux内核创建一个新进程的过程

    task_struct结构: struct task_struct {   volatile long state;进程状态  void *stack; 堆栈  pid_t pid; 进程标识符  u ...

  4. linux内核分析作业5:分析system_call中断处理过程

    1.增加 Menu 内核命令行 调试系统调用. 步骤:删除menu git clone        (tab) make rootfs 这就是我们将 fork 函数写入 Menu 系统内核后的效果, ...

  5. linux内核分析作业:以一简单C程序为例,分析汇编代码理解计算机如何工作

    一.实验 使用gcc –S –o main.s main.c -m32 命令编译成汇编代码,如下代码中的数字请自行修改以防与他人雷同 int g(int x) { return x + 3; } in ...

  6. linux内核分析作业:操作系统是如何工作的进行:完成一个简单的时间片轮转多道程序内核代码

    计算机如何工作 三个法宝:存储程序计算机.函数调用堆栈.中断机制. 堆栈 函数调用框架 传递参数 保存返回地址 提供局部变量空间 堆栈相关的寄存器 Esp 堆栈指针  (stack pointer) ...

  7. linux内核分析作业3:跟踪分析Linux内核的启动过程

    内核源码目录 1. arch:录下x86重点关注 2. init:目录下main.c中的start_kernel是启动内核的起点 3. ipc:进程间通信的目录 实验 使用实验楼的虚拟机打开shell ...

  8. linux内核分析作业4:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

    系统调用:库函数封装了系统调用,通过库函数和系统调用打交道 用户态:低级别执行状态,代码的掌控范围会受到限制. 内核态:高执行级别,代码可移植性特权指令,访问任意物理地址 为什么划分级别:如果全部特权 ...

  9. Linux内核分析作业 NO.8 完结撒花~~~

    进程的切换和系统的一般执行过程 于佳心  原创作品转载请注明出处  <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-10000 ...

  10. Linux内核分析作业 NO.7

    可执行程序的装载 于佳心  原创作品转载请注明出处  <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实 ...

随机推荐

  1. 金三银四求职季,前端面试题小梳理(HTML、CSS、JS)

    好久没写学习记录,最近太多事,又到一年求职季,都说金三银四求职季,自己也做一下最近学习的一些前端面试题梳理,还是个小白,写的不对请指正,不胜感激. HTML篇 html语义化 用语义化的代码标签书写, ...

  2. 【Ansible 文档】配置

    http://docs.ansible.com/ansible/latest/intro_configuration.html http://docs.ansible.com/ansible/late ...

  3. swift的关联类型

    一.术语:指定类型 typealias:用于给关联类型指定类型: 通过类型推断给关联类型指定类型太过烧脑: 二.类型指定 1.具体类型实现协议后,直接指定:作为普通的泛型类型使用,指定类型即可: 2. ...

  4. BZOJ3787:Gty的文艺妹子序列(分块,树状数组)

    Description Autumn终于会求区间逆序对了!Bakser神犇决定再考验一下他,他说道: “在Gty的妹子序列里,某个妹子的美丽度可也是会变化的呢.你还能求出某个区间中妹子们美丽度的逆序对 ...

  5. ubuntu 中安装 ZED SDK 及结合ROS 的使用

    双目视觉(stereo vision),由于估计深度相对容易且稠密,在姿态估计和建图时容易初始化和估计尺度,所以在三维重建,SLAM等的应用中有这广泛的应用. ZED 作为近几年出现的商业化双目传感器 ...

  6. 飞冰ICE

    一. 飞冰目标与愿景(同时也概况飞冰是什么) 飞冰是一套基于 React 的中后台应用解决方案,在阿里巴巴内部,已经有 270 多个来自几乎所有 BU 的项目在使用.经过 2 年的发展,飞冰已经是中后 ...

  7. tomcat:8080/返回404;/etc/hosts(identifier-Namespace-scope)

    我以为 就oracle 的 oracle db ,weblogic喜欢和 hostname 死磕: 没想到开源的tomcat也是如出一辙,名不正则言不顺,为什么,“名”的力量这么大呢?命名空间. 有个 ...

  8. OpenCV——视频操作基础

    读入视频: VideoCapture 类 //方法一 VideoCapture capture; capture.open("test.avi"); //方法二 VideoCapt ...

  9. C#中public与private与static

    现在静下心来想要重新细致的过一遍C#,因为自己做C#没有底气,, 闲话少说 先来一句话 public(共有的) 声明的方法和属性,可以被外部调用. private(私有的) 声明的方法和属性,只能在本 ...

  10. jqgrid 让隐藏的列在编辑状态时出现且可编辑

    有时,我们需要隐藏一个列数据,但在启动编辑时又能够被编辑. 1.设置列为编辑:editable: true 2.设置 editrules属性值为: edithidden: true colModel: ...