zoukankan      html  css  js  c++  java
  • 2018-2019-1 20189206 《Linux内核原理与分析》第二周作业

    Linux内核分析 第二周学习


    知识总结

    操作系统与内核

    • 操作系统 指在整个系统中负责完成最基本功能和系统管理的那些部分
    • 内核 实际是操作系统的内在核心
      • 内核独立于普通应用程序,拥有受保护的内存空间和访问硬件设备的所有权限,这种空间被称为内核空间
      • 当内核运行的时候,系统以内核状态进入内核空间执行
      • 当应用程序通过系统调用与内核通信时,我们称内核正在代其执行
        • 应用程序称为通过系统调用在内核空间运行,内核被称为运行于进程上下文中
        • 实际上,应用程序通常调用库函数,然后库函数通过系统调用界面,让内核完成不同任务
      • linux是一个单内核,但拥有模块化设计、抢占式内核、支持内核线程及动态装载内核模块的能力

    计算机工作原理

    冯诺依曼体系结构

    根据冯诺依曼提出的理论:把程序本身当作数据来对待,程序和数据处理用同样的方式

    • CPU 是计算机硬件的基础,与内存和I/O设备进行交互,其中PC程序寄存器总是指向下一条要执行的命令
      • API 程序与计算机的接口
      • ABI 程序与CPU的接口

    x86-32汇编基础

    CPU的寄存器

    8086CPU中一共有14个16位寄存器,分别为:

    • 数据寄存器
      • AX 累加寄存器
      • BX 基地址寄存器
      • CX 计数器寄存器
      • DX 数据寄存器
    • 指针寄存器
      • SP 堆栈指针寄存器
      • BP 基指针寄存器
    • 变址寄存器
      • SI 源变址寄存器
      • DI 目的变址寄存器
    • 控制寄存器
      • IP 指令指针寄存器
      • FLAG 标志寄存器
    • 段寄存器
      • CS 代码段寄存器
      • DS 数据段寄存器
      • SS 堆栈段寄存器
      • ES 附加段寄存器
        【注】在32位CPU中,32位寄存器EAX EBX ECX EDX 不仅可以传送数据、暂存数据保存算数罗运算结果,还可以作为指针寄存器。
        在定位一个指令时,使用CS:EIP来指明它的地址
    寻址方式和常用汇编指令
    • 操作数

      • 立即数 即常数,用$后跟一个数值表示
      • 寄存器数 表示某个寄存器保存的值 用%eax表示
      • 存储器引用 根据计算出来的有效地址,访问存储器的某个位置
    • 常见汇编指令

      • 寄存器寻址 操作寄存器而不和内存打交道
        • movl %eax,%edx 表示将寄存器eax中的内容放到ebx中
      • 立即寻址
        • movl $0x123, %eax 表示将0x123这个16进制数放入eax这个寄存器中
      • 直接寻址
        • movl 0x123,%edx 表示将0x123内存地址所指向的那块内存里存储的数据放到EDX寄存器中
      • 间接寻址
        • movl (%ebx),%edx 表示取ebx寄存器中存储的地址的值,放入edx中
      • 变址寻址
        • movl 4(%ebx),%edx 表示在间接寻址的基础上,在原地址上加上一个立即数4
      • 出栈入栈
        • pushl %eax
          • 相当于subl $4,%esp movl %eax,(%esp) 将栈顶指针向下移动一位,再将eax的内容放入esp指向的内存中
          • 由于堆栈是向下增长的,所以用减指令栈顶指针向下移动
        • popl %eax
          • 相当于movl (%esp),%eax addl $4,%esp 将栈顶数值放在eax寄存器中,esp指针向上移动,栈在收缩
      • 函数调用
        • call 0x12345
          • 相当于pushl %eip(*) movl $0x12345, %eip(*) 将当前eip(指向下一条要运行的指令地址)入栈,然后将新的地址赋给eip
          • 由于不能直接对eip进行操作,所以以上的等价操作都是伪指令
      • 函数返回
        • ret
          • 相当于popl %eip(*) 就是把当前堆栈栈顶的一个存储单元放到eip寄存器中
      • 宏指令
        • leave 用来撤销函数堆栈
          • 相当于movl %esp,%ebp popl %ebp
        • enter 用来建立函数堆栈
          • 相当于pushl %ebp movl %esp,%ebp

    实验部分

    实验一 反汇编一个简单的C程序

    通过linux系统的gcc编译命令的参数-S 编译出汇编程序main.s 利用vim查看其中的代码。

    其中,产生的汇编代码中所有以.开头的命令都是用于链接的辅助信息,为了查看到纯汇编程序,我们可以将所有带点的命令删除,得到的就是汇编代码。

    对汇编代码的分析

    • pushl %ebp ebp指针指向栈底,将ebp指向的位置入栈,栈顶指针esp向下移动
    • movl %esp , %ebp ebp和esp指向同一个位置
      上面两条命令相当于建立main函数自己的函数调用空间
    • subl $4,%esp esp指针减4 表示指针向下移动一个位置
    • movl $2,(%esp) 将立即数2存入esp指向的位置
    • call f 相当于 pushl %eip
      movl f,%eip 实际上就是将eip指针指向的代码地址入栈,之后将eip指针指向f函数,实现了函数的跳转
      之后再跳转执行f函数的代码。

    【注】EAX寄存器是默认存储函数返回值的寄存器
    所有函数的头两行指令用于初始化函数自己的函数调用堆栈空间

    对应的堆栈变化




    遇到的问题

    1. movl %eax,%ebx 是将eax寄存器中存储的内容给了ebx
      movl %esp,%ebp 是将ebp指针指向和esp指针指向的同一个位置
      我刚开始就对这两条命令不是很清楚,为什么第一条就可以是存储内容,而第二条就是改变了指针的指向。后来我反应过来,esp和ebp这两个寄存器存储的是地址,是堆栈的栈底和栈顶的位置,从实质来看,改变的仍旧是寄存器中的内容。

    2.刚开始的堆栈总是画不对,后来发现是概念错误

    pushl %esp 首先将esp指针向下移动一位,再将esp指向的地址入栈。

  • 相关阅读:
    POJ 1401 Factorial
    POJ 2407 Relatives(欧拉函数)
    POJ 1730 Perfect Pth Powers(唯一分解定理)
    POJ 2262 Goldbach's Conjecture(Eratosthenes筛法)
    POJ 2551 Ones
    POJ 1163 The Triangle
    POJ 3356 AGTC
    POJ 2192 Zipper
    POJ 1080 Human Gene Functions
    POJ 1159 Palindrome(最长公共子序列)
  • 原文地址:https://www.cnblogs.com/zz-1226/p/9822313.html
Copyright © 2011-2022 走看看