一、《linux内核分析》实验一实验报告

       在进行实验楼操作之前,先听授了网易云课堂中孟老师关于“计算机是如何工作的?”的介绍。其中主要涉及到了冯诺依曼体系结构,或称为存储程序计算机、从硬件角度和程序员的角度对计算机中内存与CPU之间关系的理解、API——程序与计算机的接口界面、ABI——程序与CPU的接口界面、16位和32位以及64位的X86体系结构的寄存器,其中印象最深的是堆栈指针、段寄存器和EIP等。而对于堆栈指针,在本科阶段学习数据结构课程的时候已经有过相关的编程与实践,但是却没有真正在汇编中进行过相关的操作。紧接着做了一下实验楼中的实验——反汇编一个简单的C程序,下边是我的操作过程,以及我对这部分汇编代码的理解。
C程序代码:

       实验楼给出的代码中,简单修改了一下参数,最后的返回结果为11。那么计算机是如何执行的呢?C作为一门高级程序设计语言,计算机是读不懂这段代码的。根据孟老师的讲解,计算机首先借助于gcc命令将这段程序编译成汇编程序,然后通过汇编翻译程序将其翻译成计算机二进制机器指令,最后CPU中的IP寄存器读取到内存中这段程序对应的一大串二进制指令进行计算执行,最后将结果进行输出。实验中,将这段程序保存为main.c文件,通过gcc main.c进行编译,得到一个a.out的文件,执行./a.out,最后通过gcc -S -o main.s main.c -m32命令将main.c的源程序反汇编成对应的汇编代码,按孟老师所讲,main.s里面所有以.开头的代码主要是一些用于链接的辅助信息,并不会被执行,在这里为了方便学习,可以先把它们删除掉,从而得到一个纯净的汇编代码,如下图所示:

       不难发现,不管是main函数还是g和f函数,它们编译成汇编之后,前两行的汇编指令都是相同的。这个和函数栈帧有关。机器是用栈来传递过程参数,存储返回信息的过程,过程调用开始时,都会为当前这个过程建立一个栈帧。%ebp是帧指针,%esp是栈指针。这两句的意思是保存旧的帧,创建新的栈帧。由于函数可以调函数,这里的当前基地址,实际上是上一个函数的栈基地址。在这里,f函数中的这两条指令,实际上是保存的main函数的栈基地址、g里边保存的是f函数的栈基地址。
接着分析:
       subl $4, %esp
       movl $2, (%esp)
       参数进栈,将立即数2保存到esp所指向的内存地址——栈顶。然后执行call指令,调用f函数。f函数前两行指令保存main函数的栈基地址,然后接着参数进栈,将立即数8保存到栈顶,并与立即数3相加,并将结果放入栈顶。接着调用g函数。那么问题来了,函数是如何退出的呢?观察mian和f函数,发现退出函数使用的如下指令:
       leave
       ret
leave指令相当于如下指令:
       movl %ebp, %esp //清空当前函数所使用的栈
       popl %ebp //把ebp恢复到前一个函数的栈基地址
接着ret恢复指令指向:popl %eip。
       为什么g函数没有leave呢?因为g函数内部没有任何的变量声明和函数调用,栈一直都是空的,所以编译器优化了指令。下边以一张图来说明上边指令的执行过程。

实验补充:程序执行过程堆栈图分析

二、《linux内核设计与实现》第1、2、18章学习总结

       从第1章的linux内核简介到第2章的从linux内核出发,再到第18章所讲述的如何对linux内核进行调试以及调试中需要注意的一些事项和问题,最后结合网易云课堂孟老师对如何构造一个简单的linux系统MenuOS的视频讲解与操作演示,我开始尝试用自己的Linux系统环境来搭建这样一个MenuOS,首先是从https://www.kernel.org中下载到linux-3.18.6.tar.xz的源代码,然后进行解压缩、编译;这个过程还算顺利。不过编译的时间确实比较长,花了大概15分钟。但是,在制作根文件系统时,遇到了一些问题,当执行:

gcc -o init linktable.c menu.c test.c -m32 -static –lpthread

命令时,遇到了如下问题:

通过参考nixCraft的描述,发现我自己的系统环境中缺少32位嵌入式GNU的C库,安装后得以解决了。

yum install glibc-devel.i686

可是还存在一个问题,如下:

[root@localhost menu]# gcc -o init linktable.c menu.c test.c -m32 -static –lpthread

gcc: –lpthread: No such file or directory

       对于这个问题,网上尝试查找相关解决办法,但未能解决。很遗憾没能成功制作出根文件系统,时间原因,博客就先写到这里,后续遗留问题将跟进解决。

参考文档:

20169211《Linux内核原理与分析》第二周作业的更多相关文章

  1. 2019-2020-1 20199303<Linux内核原理与分析>第二周作业

    2019-2020-1 20199303第二周作业 1.汇编与寄存器的学习 寄存器是中央处理器内的组成部份.寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令.数据和位址.在中央处理器的控制部件中 ...

  2. 20169219 linux内核原理与分析第二周作业

    "linux内核分析"的第一讲主要讲了计算机的体系结构,和各寄存器之间对数据的处理过程. 通用寄存器 AX:累加器 BX:基地址寄存器 CX:计数寄存器 DX:数据寄存器 BP:堆 ...

  3. 2019-2020-1 20199314 <Linux内核原理与分析>第二周作业

    1.基础学习内容 1.1 冯诺依曼体系结构 计算机由控制器.运算器.存储器.输入设备.输出设备五部分组成. 1.1.1 冯诺依曼计算机特点 (1)采用存储程序方式,指令和数据不加区别混合存储在同一个存 ...

  4. Linux内核原理与分析-第二周作业

    写之前回看了一遍秒速五厘米:如果

  5. Linux内核原理与分析-第一周作业

    本科期间,学校开设过linux相关的课程,当时的学习方式主要以课堂听授为主.虽然老师也提供了相关的学习教材跟参考材料,但是整体学下来感觉收获并不是太大,现在回想起来,主要还是由于自己课下没有及时动手实 ...

  6. 2019-2020-1 20199314 <Linux内核原理与分析>第一周作业

    前言 本周对实验楼的Linux基础入门进行了学习,目前学习到实验九完成到挑战二. 学习和实验内容 快速学习了Linux系统的发展历程及其简介,学习了下的变量.用户权限管理.文件打包及压缩.常用命令的和 ...

  7. 2018-2019-1 20189221《Linux内核原理与分析》第一周作业

    Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...

  8. 2020-2021-1 20209307 《Linux内核原理与分析》第九周作业

    这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)> 这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第九周作业> 这个作业的目标 & ...

  9. 20169212《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...

  10. 20169210《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...

随机推荐

  1. CentOS7,安装Tomcat8.5、JDK1.8,并设置开机启动(Linux CentOS Tomcat、JDK+Tomcat、Tomcat开机自启动)

    1.下载JDK1.8.Tomcat8 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.ht ...

  2. 数学&搜索:博弈论之极大极小搜索与alpha-beta减枝

    目的是寻找最优的方案使得自己能够利益最大化. 基本思想就是假设自己(A)足够聪明,总是能选择最有利于自己的方案,而对手(B)同样足够聪明,总会选择最不利A的方案 对抗搜索就是对于先手来说,取后手中状态 ...

  3. C#为何不推荐在构造函数中访问虚成员

    如果在一个类中定义了虚属性或者虚方法,又在构造函数中访问了这个虚属性或方法,此时VisualStudio是不会给出警告,并且编译也没有问题,但是如果安装了Resharper插件则会给出警告提示:&qu ...

  4. Delphi 常用数据类型 字符串类型 数据类型等等

    字符串类型 Delphi有三种类型的字符: ●AnsiChar这是标准的1字节的ANSI字符,程序员都对它比较熟悉. ●WideChar这是2字节的Unicode字符. ●Char在目前Delphi早 ...

  5. JSP和Servlet面试题

    1.讲下servlet的执行流程. Servlet的执行流程也就是servlet的生命周期,当服务器启动的时候生命周期开始,然后通过init()<启动顺序根据web.xml里的startup-o ...

  6. sublime出现卡顿的现象

    这几天,用sublime总是写一个代码就卡顿,卡卡卡,,,,要死的~ 最后,才发现是因为安装了一个插件:GitGutter插件,所以,小伙伴们请跟上我的节奏~~~~~ (1)Ctrl + Shift ...

  7. php简单文件管理器——php经典实例

    <html> <head> <title>文件管理</title> <meta charset='utf-8' /> </head&g ...

  8. css3旋转、过渡、动画属性

    1.transform 该属性对元素进行旋转.缩放.移动和倾斜 translate元素从当前位置移动 rotate元素顺时针旋转 scale元素的尺寸增大或减小 skew元素翻转 2.transiti ...

  9. Perl6 必应抓取(1):测试版代码

    一个相当丑漏的代码, 以后有时间再优化了. 默认所有查找都是15页, 如果结果没有15页这么多估计会有重复.速度还是很快的. sub MAIN() { my $fp = open 'bin_resul ...

  10. Django 自定义分页类

    分页类代码: class Page(object): ''' 自定义分页类 可以实现Django ORM数据的的分页展示 输出HTML代码: 使用说明: from utils import mypag ...