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指向的地址入栈。

  • 相关阅读:
    接口测试 API测试
    接口测试 JMeter 开坑
    【测试笔记】集成测试 自顶向下 自底向上
    白盒测试 各类覆盖方法辨析
    eureka 管理界面打不开
    Spring Boot 2.0 Admin
    spring swagger2配置
    解决 Registered driver with driverClassName=oracle.jdbc.driver.OracleDriver was not found, trying direct instantiation.
    springboot+mybatis在插入空值时报错的问题
    Vue Cli 3代理配置
  • 原文地址:https://www.cnblogs.com/zz-1226/p/9822313.html
Copyright © 2011-2022 走看看