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

第一章 计算机工作原理

一、 根据实验研究计算机是如何工作的?

第一步:建立一个main.c文件,使用vi编辑器,把C程序输入到main.c,输入时要按“shift”+“i”,意为插入,输入完成,先按“Esc”退出插入功能,再按“shift”+“wq!”保存并退出,可以用

cat main.c

实现对文件内容的查看。实验截图如下:

第二步:使用gcc命令对.c文件进行编译处理,自动生成a.out文件,使用“./”命令执行文件内容,再使用“echo”查看结果,实验代码如下:

第三步:确认实验结果无误后,输入

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

编译成32位汇编程序,以便于后续分析。

第四步:打开main.s文件,把前面是“.”的代码行删去,结合教材和云班课视频对汇编代码进行分析,充分体会计算机的工作原理,查看的main.s文件内容如下:

第五步:分析每行语句寄存器发生的变化,进而体会计算机工作原理机制。具体分析如下(为了让栈以及各寄存器的变化看起来更直观,我用画图的方法表示,前面标号表示代码所在行号):

二、本章学习中遇到的问题及解决方法

  1. 问题一:学习到教材P8有关寻址指令的解释时,对其中提到的数据、数值、数的概念搞不清楚,不知道寄存器存的到底是地址还是数?

    解决方法:后通过网上搜资料,明白了寄存器有的存地址,有的存数。那么,问题又来了。

  2. 问题二:间接寻址那提到“%ebx寄存器存的值是一个内存地址”,万一这个寄存器存的正好是一个数怎么实现间接寻址?变址寻址那提到“把这个ebx寄存器存储的数值加4”,万一正好存的是一个地址呢?

    解决方法:带着疑惑听了云班课中1-2的视频,豁然开朗,此处说到的数值是一个十六进制数,其实就是一个指向内存的地址,上面的疑问也就都明白了。

  3. 问题三:变址寻址movl 8(%ebp), %eax中ebp寄存器存放的数值有没有变化?

    解决方法:经网上搜索,ebp寄存器存放的数值没有变化。

  4. 问题四:教材P12中如图的汇编代码中“pushl %esp”esp既作为操作数又被push指令使用是怎么操作的?以及最后两句的栈和寄存器是怎么变化的?

    解决方法:书上有些看不懂,后看了云班课的视频,明白了变化过程,具体分析如下:

第1句:将8立即数压栈,此时esp指针指向地址单元1(这里假设内存单元从0增加),ebp仍指向栈底;

第2句:esp的内容放到ebp中,即ebp也指向单元1;

第3句:esp的内容压栈,故esp1压栈,esp指向的单元2;

第4 句:立即数8压栈,此时esp指向esp3;

第5 句:esp存放地址加4,即返回到上一个存储单元,此时,esp指向esp2;

第6句:将esp指向的数值放到esp,这里,esp指向的数值是esp1,该命令使得esp指向esp1,后又需要数值加4,故最后,esp指向单元0,即栈顶,ebp仍指向单元1。

三、本章知识总结

  1. 冯·诺依曼体系结构的要点

    • 计算机硬件由运算器、存储器、控制器、输入设备和输出设备五大基本组件构成;

    • 计算机内部采用二进制来表示指令和数据;

    • 将编好的程序和原始数据事先存入存储器中,然后再启动计算机工作,这就是存储程序的基本含义。

  2. 中央处理器(CPU)由运算器、控制器和一些特殊寄存器组成,与内存和I/O设备进行交互,它们之间通过总线连接,内存中存放指令和数据,CPU负责解释和执行这些指令,这也是计算机可以自动化执行程序的原理。

  3. 几个经常用到的寄存器

    AX ( Accumulator ) :累加寄存器

    BP ( Base Pointer ) :基指针寄存器,指向栈底,此处指相对栈底

    SP ( Stack Pointer ) :堆栈指针寄存器,指向栈顶

    IP ( Instruction Pointer ) :指令指针寄存器,除特殊指令外,该指针自动指向下一条指令的地址

  4. 五种寻址方式

    寄存器寻址,如:movl %eax, %edx

    立即寻址,如:movl $8, %edx 以上两种和内存没有关系

    直接寻址,如:movl 0x12, %edx

    间接寻址,如:movl ( %ebx ), %edx

    变址寻址,如:movl 4( %ebx ), %edx

  5. 六种常用汇编指令

    • push 压栈,pushl %eax相当于
    subl $4, %esp
    movl %eax, (%esp)
    
    • pop 出栈,popl %eax 相当于
    movl (%esp), %eax
    addl $4, %esp
    
    • call 函数调用,call 0x1234 相当于
    pushl %eip (*)
    movl $0x1234, %eip (*)
    
    • ret 函数返回,相当于
    popl %eip (*)
    
    • leave 撤销函数堆栈,相当于
    movl %ebp, %esp
    popl %ebp
    
    • enter 建立函数堆栈,相当于
    pushl %ebp
    movl %esp,%ebp
    
posted @ 2019-09-22 00:22  梁旭20199320  阅读(183)  评论(0编辑  收藏  举报