• 2019-2020-1 20199308《Linux内核原理与分析》第二周作业


    《Linux内核分析》

    第一章 计算机工作原理

    1.1 存储程序计算机工作模型

    • 冯·诺依曼体系结构
      各种计算机体系结构需要遵从的一个“客观规律”
      • 结构图

      • 冯·诺依曼体系结构的核心是存储程序计算机。

      • 内存保存指令和数据,CPU负责解释和执行这些指令,它们通过总线连接起来。
        存储程序计算机工作原理示意图

      • 对于x86-32计算机,有一个EIP寄存器指向内存的某一条指令,EIP是自动加一的(加一条指令)。

    1.2 x86-32 汇编基础

    1.2.1 x86-32 CPU的寄存器

    • 开头为E的寄存器,一般是32位的。

    • 32位寄存器EAX、EBX、ECX和EDX不仅可以传送数据、暂存数据保存算数逻辑运算结果,还可以作为指针寄存器。

    • 段寄存器

    • 代码段:使用CS:EIP来准确指明一个指令的内存地址(即首先需要知道代码在哪一个代码段里,然后需要知道指令在代码段内的相对偏移地址EIP)。

    • 堆栈段:每一个进程都有自己的堆栈段。

    • 开头带R的都是指64位寄存器。

    1.2.3 寻址方式和常用汇编指令

    • 最常见的汇编指令是mov指令,movb是指8位;movw是指16位;movl是指32位;movq是指64位。

    • 寻址方式

    • x86-32中的大多数指令都能直接访问内存,但还有一些指令能直接对内存操作,如mov,push/pop等。

    • 压栈:pushl表示32的push:

    pushl %eax
    

    就是把EAX寄存器的值压到堆栈栈顶。实际上是两个动作:
    ①把堆栈的栈顶ESP寄存器的值减4。(因为堆栈是向下增长的,所以用减指令subl,也就是在栈顶预留出一个存储单元

    subl $4, %esp
    

    ②间接寻址,就是把EAX寄存器的值放到ESP寄存器所指向的地方,这时ESP寄存器已经指向预留出的存储单元。

    movl %eax, (%esp)
    
    • 出栈:
    popl %eax
    

    从堆栈的栈顶取一个存储单元,从堆栈栈顶的位置放到EAX寄存器里。实际上也是两个动作:
    ①把栈顶的数值放到EAX寄存器里。

    movl (%esp), %eax
    

    ②用指令addl把栈顶加4,相当于栈向上回退了一个存储单元的位置,也就是栈在收缩。

    addl $4, %esp
    

    每次执行指令pushl栈都增长,执行指令popl栈都收缩

    • call指令是函数调用,相当于两个动作:
    push %eip
    movl f %eip
    
    • ret指令是函数返回
    • EIP寄存器不能被程序员直接修改,只能通过专用指令(如call、ret和jmp等)间接修改。

    1.2.4 汇编代码范例解析

    以下两个片段变化的效果是一样的

    以下片段稍有复杂(书P12)

    1.3 汇编一个简单的C语言程序并分析其汇编指令执行过程

    • “ls”命令查看目录

    vi main.c
    ```命令打开VIM编辑main.c文件
    
       ![](https://img2018.cnblogs.com/blog/1800809/201909/1800809-20190921204953711-80431995.png)
    
    - 
    
    

    gcc main.c

    echo $?

    
    ![](https://img2018.cnblogs.com/blog/1800809/201909/1800809-20190921222911758-2119304015.png)
    
    - 
    
    

    gcc -S -o main.s main.c -m32

    在VIM编辑器中用
    

    g/.s*/d

    
    ![](https://img2018.cnblogs.com/blog/1800809/201909/1800809-20190921223431249-1223513638.png)
    
    - 分析上述“干净”的汇编代码
    

    1 g:
    2 pushl %ebp //将EBP压栈,将位置4存到位置7;ESP也指向位置7。
    3 movl %esp, %ebp //将EBP也指向位置7。
    4 movl 8(%ebp), %eax //EBP变址寻址,加8,即指向位置7不动,并把位置5的内容(即立即数8)放入EAX(取出函数g的参数)。
    5 addl $7, %eax //将立即数7加到EAX中,即4+7,EAX为11。
    6 popl %ebp //将位置7的内容(即位置4)放回EBP(即恢复函数f的函数调用堆栈基址EBP),即EBP指向位置4;同时ESP加4,指向位置6。
    7 ret //(popl%eip)将ESP所指向的内容,即行号15放入EIP,即EIP指向行号15;同时ESP加4,即指向位置5。
    8 f:
    9 pushl %ebp //将EBP向下移动(从EIP的位置3开始),指向位置4。
    10 movl %esp, %ebp //将ESP也指向EBP的位置4。
    11 subl $4, %esp //ESP减4,指向位置5。
    12 movl 8(%ebp), %eax //EBP变址寻址8,向上移动两个存储单元即加两个标号的位置,即指向位置2;并将位置2存储的立即数8放到EAX中。
    13 movl %eax, (%esp) //将EAX放入ESP中,即立即数8放入位置5。
    14 call g //类似第22行,将ESP指向位置6,;把EIP行号15放到位置6,并指向函数g的位置即第2行。
    15 leave //撤销函数堆栈,等价于=(movl %ebp,%esp和popl %ebp),即将EBP的内容(位置4)放入ESP,即ESP也指向位置4;然后把位置4的内容(即位置1)放回EBP,即EBP指向位置1;同时ESP加4,指向位置3。
    16 ret //将ESP所指向的位置3的内容(即行号23)放到EIP中,即EIP指向行号23,;同时ESP加4,指向位置2。
    17 main:
    18 pushl %ebp //开始执行第一条指令,EIP自动加1即指向行号19;把EBP的值压栈,先将EBP指向位置1,再将EBP的值标号0。
    19 movl %esp, %ebp //EIP自动加1即指向行号20;将EBP指向位置1。
    20 subl $4, %esp //EIP自动加1即指向指向行号21;将ESP减4,即向下移动,指向位置2。
    21 movl $4, (%esp) //EIP自动加1即指向行号22;把立即数4放入ESP,仍指向位置2(20和21行同作为压栈f函数所需参数)。
    22 call f //执行此行时,EIP已经自动加1指向了下一行即指向行号23(pushl %eip),然后将函数f的开始指令放入EIP(movl f %eip),即EIP指向函数f的位置即第9行。
    23 addl $1, %eax //将EAX加立即数1,即11+1,EAX的值为12,(EAX是默认存储函数返回值的寄存器)。
    24 leave //撤销函数main堆栈,将EBP和ESP都指回位置1,同时把位置1存储的内容(即位置0)放到EBP,即EBP指向位置0;并ESP加4,也指向位置0。
    25 ret //指令结束。

    
    
      - leave指令等价于令:
    

    movl %ebp,%esp
    popl %ebp

    
      - enter指令等价于:
    

    pushl %ebp
    movl %esp, %ebp

  • 相关阅读:
    openlayers5-webpack 入门开发系列一初探篇(附源码下载)
    leaflet-webpack 入门开发系列二加载不同在线地图切换显示(附源码下载)
    Cesium-空间分析之通视分析(附源码下载)
    Geoserver2.15.1 配置自带 GeoWebCache 插件发布 ArcGIS Server 瓦片(附配置好的 Geoserver2.15.1 下载)
    leaflet-webpack 入门开发系列一初探篇(附源码下载)
    maven学习(上)- 基本入门用法
    Java面试11|Maven与Git
    必须学会git和maven
    Git 安装和使用教程
    用git,clone依赖的库
  • 原文地址:https://www.cnblogs.com/hsj910/p/11563286.html
Copyright © 2020-2023  润新知