zoukankan      html  css  js  c++  java
  • 庖丁解牛Linux内核学习笔记(1)--计算机是如何工作的

    存储程序计算机模型

    冯诺依曼体系结构

    冯诺依曼体系结构是存储程序计算机,什么叫存储程序计算机?从硬件角度说,假设有cpu和内存,两者通过总线连接,在cpu内部有一个寄存器叫ip(instruction pointer),即X86型CPU中的指令指针寄存器(相当于ARM型CPU中的程序计数器PC)。ip总是指向内存中的代码段,然后cpu从ip指向的区域取出一条指令,并且执行该指令,然后ip自动加1,指向紧邻的下一条指令,cpu取出该指令并执行,然后ip再自动加1,cpu再执行。。。这样,程序代码存储在内存里,cpu通过ip寄存器依次顺序执行程序代码。这就是硬件角度的冯诺依曼体系结构,目前所有的具有计算功能的计算机都是冯诺依曼体系结构。
    从程序员角度说,存储程序计算机可以抽象为下图,其中cpu被抽象为for循环,总是在执行next struction。内存里主要是保存instruction(指令)和data数据,也就是代码区和数据区。工作原理是内存存储指令和数据,cpu逐条解释执行指令。

    API和ABI

    CPU识别什么样的指令,涉及到API(Application Programming Interface,应用程序编程接口)和ABI(Application Binary Interface应用程序二进制接口),其中API是程序员与计算机的接口界面,ABI是程序与CPU的接口界面,这个接口界面涉及到3个方面的内容:1)汇编指令编码 2)指令使用过程中使用到的寄存器3)大多指令可以访问内存。其中在x86机器上,cpu的执行的每条指令都存放在eip(32位机的指令寄存器),eip是自增的,通过eip自增可实现cpu顺序执行指令,而eip也是可以被jmp(跳转指令)、ret、call等指令修改的,从而实现cpu跳转执行指令。

    x86汇编基础

    x86 CPU中的寄存器

    x86 cpu中的寄存器有32位、16位、8位的,16位的寄存器叫做AX、BX、CX、DX、BP、SI、DI、SP等,32位寄存器是将16位的进行扩展,然后在寄存器命名时添加E,比如16位寄存器AX扩展为32位命名为EAX,寄存器分为通用寄存器和专用寄存器,具体用途如下:

    段寄存器属于专用寄存器:

    在段寄存器中代码段和堆栈段使用率较高,因为指令存储在代码段,CPU在取指令时使用cs:eip来准确定位一个指令,另外每一个进程都有自己的堆栈,所以代码段和堆栈段使用频繁一些。除了上述寄存器还需要了解的是一个标志寄存器EFLAGS,该寄存器标识当前处理器处于什么状态。
    当前主流的机器是x86_64位机,在核心机制上x86_64和x86差别不大,只是寄存器从32位扩展为64位,命名的时候在寄存器名称前面加R:RAX、RBX等等,状态寄存器命名为RFLAGS等。

    x86汇编指令和寻址方式

    比较常用的汇编指令有mov指令、push、pop指令、call指令和ret指令。其中mov指令是将第一个操作数数据存入第二个操作数中。根据不同的寻址方式数据来源和存储位置均可能为寄存器、存储器等。语法中%表示寄存器,$表示立即数,()表示取内存中的数据,*表示程序员不能直接修改eip,可使用call和ret修改。

    push、pop指令是入堆栈和出堆栈的指令,具体可参考 Push, Pop, call, leave 和 Ret 指令图解中的图解~call指令和ret指令是一一对应的,一个是保存eip寄存器的值入栈,然后将子函数的地址写入eip,ret是将保存入堆栈的eip的值恢复回去。

    堆栈的概念

    堆和栈是数据结构,需要注意的是,进程在内存里的结构如下图:

    上图中的堆栈准确的说应该叫做堆区和栈区,其中箭头是指各个区域的增长方向。具体堆和栈的区别可参考堆和栈的区别

    总结

    存储程序计算机模型相关知识、CPU中的寄存器这两方面内容在《计算机组成原理》课程中详细介绍,汇编指令以及寻址方式会在《嵌入式系统设计》课程里介绍,寻址方式在计算机组成原理中也会介绍。

  • 相关阅读:
    oracle客户端连接服务器基本教程
    java中字符串处理、串联和转换的几个常用方法,以及如果需要自己编程实现的具体实施步骤。
    面试相关
    java中byte是什么类型,和int有什么区别
    (华为机试大备战)java。多了解了解最常用的那个类库的方法对处理字符串的方法
    (华为)以下代码片段将创建一个仅保存大写字符的字段。
    (华为)以下代码片段将创建一个仅保存大写字符的字段。
    每个程序中只有一个public类,主类?
    我的第一个长程序,虽然是直接抄了书上,可是还是出现了两次拼写错误,最终还是找到异常的答案,改过来了。
    实践证明:当类想实现两个监听接口的时候,必须把两个都设置成内部类,不可能一个是外部类实现,一个是内部类实现。这样容易捕获错误,出现异常。
  • 原文地址:https://www.cnblogs.com/c-programing-language/p/6841227.html
Copyright © 2011-2022 走看看