Linux内存管理-预备篇(寄存器)

前言(wxy):说到寄存器,迷迷茫茫好多年,一方面记不住每个寄存器的名称以及作用,另一方面迷惑于寄存器的名称,常常会有一个疑惑就是说道寄存器的种类,怎么各种版本,他们到底什么关系,基本上所有的博客都是直接拷贝别人的,而且也不 说明他们到底什么关系,指示罗列概念,我百度了一下午也没查出个所以然,真TM生气......今天终于解开了这个谜团,原来CPU寄存器分为两类:

用户可见寄存器,用户可以对这些寄存器进行编程,还可以通过优化使CPU因使用这类寄存器而减少对主存的访问次数,也就是说我们使用汇编语言可以直接对其操作;

控制和状态寄存器,用户不可对其进行编程,他们被控制部件使用,以控制CPU的操作,也可以被带有特权的操作系统程序使用,从而控制程序的执行。

 

一:控制和状态寄存器

参见:https://blog.csdn.net/kwame211/article/details/77773621

CPU中至少要有六类寄存器:指令寄存器(IR)、程序计数器(PC)、地址寄存器(AR)、数据寄存器(DR)、累加寄存器(AC)、程序状态字寄存器(PSW)。这些寄存器用来暂存一个计算机字,其数目可以根据需要进行扩充。

1. 数据寄存器(Data Register,DR/MDR)又称数据/指令缓冲寄存器

数据寄存器用来暂时存放由主存储器读出的一条指令或一个数据字;反之,当向主存存入一条指令或一个数据字时,也将它们暂时存放在数据寄存器中; 在单累加器结构的运算器中,还可兼作操作数寄存器。

2. 地址寄存器(Address Register,AR/MAR)用来保存CPU当前要所访问的主存单元的地址

当CPU和主存进行信息交换,即CPU向主存存入数据/指令或者从主存读出数据/指令时,都要使用该地址寄存器进行寻址,接着用数据寄存器存放寻址得来的数据。

如果我们把外围设备与主存单元进行统一编址,那么,当CPU和外围设备交换信息时,我们同样要使用地址寄存器和数据寄存器。

3. 指令寄存器(Instruction Register,IR)用来保存当前正在执行的一条指令

当执行一条指令时,首先把该指令从主存读取到数据寄存器(DR)中,然后再传送至指令寄存器。

指令包括操作码和地址码两个字段,为了执行指令,必须对操作码进行测试,识别出所要求的操作,指令译码器(Instruction Decoder,ID)就是完成这项工作的。指令译码器对指令寄存器的操作码部分进行译码,以产生指令所要求操作的控制电位,      并将其送到微操作控制线路上,在时序部件定时信号的作用下,产生具体的操作控制信号。

4. 程序计数器(Program Counter,PC)用来指出下一条指令在主存储器中的地址

在程序执行之前,首先必须将程序的首地址,即程序第一条指令所在主存单元的地址送入PC,因此PC的内容即是从主存提取的第一条指令的地址。

当执行指令时,CPU能自动递增PC的内容,使其始终保存将要执行的下一条指令的主存地址,为取下一条指令做好准备。若为单字长指令,则(PC)+1àPC,若为双字长指令,则(PC)+2àPC,以此类推。

但是,当遇到转移指令时,下一条指令的地址将由转移指令的地址码字段来指定,而不是像通常的那样通过顺序递增PC的内容来取得。

因此,程序计数器的结构应当是具有寄存信息和计数两种功能的结构。

5. 累加寄存器(Accumulator,AC)是一个通用寄存器。

当运算器的算术逻辑单元ALU执行算术或逻辑运算时,为ALU提供一个工作区,可以为ALU暂时保存一个操作数或运算结果。显然,运算器中至少要有一个累加寄存器。

6. 程序状态字寄存器(Program Status Word,PSW),用来表征当前运算的状态及程序的工作方式。

程序状态字寄存器用来保存由算术/逻辑指令运行或测试的结果所建立起来的各种条件码内容,如运算结果进/借位标志(C)、运算结果溢出标志(O)、运算结果为零标志(Z)、运算结果为负标志(N)、运算结果符号标志(S)等,这些标志位通常用1位触发器来保存。除此之外,程序状态字寄存器还用来保存中断和系统工作状态等信息,以便CPU和系统及时了解机器运行状态和程序运行状态。因此,程序状态字寄存器是一个保存各种状态条件标志的寄存器。

小小结:运行一段程序,都是怎么使用这些寄存器呢?

程序/指令是存放在存储系统中的,由CPU负责取指令,分析指令,执行指令,然后再读.....第一条指令可以由系统设定也可以人为指定,具体的工作为

从PC中读取(第一条)指令的地址到AR中,根据AR寻址读取出数据(在这里是指令)到DR中,再因为是指令所以交给IR,进而由逻辑运算部件ALU去做运算

但是做运算光有指令不行,还要由被计算的数据啊,所以ALU还会访问DR(这里是数据)以及其他用户操作的寄存器,

运算的过程中还会产生中间值,那么就需要借助AC来存放了

整个运算的过程中,PSW作为辅助提供条件码等,以及记录状态等

 

二,用户可见寄存器

以32位架构为例,CPU相关器存器有10个32位和6个16位的,分三大类,(wxy:为了能够很好的记住这些寄存器的作用,最好记住他们的英文,理解单词的含义)

通用寄存器(Extended * register): 不是专用的,几乎是个函数都要用到这些寄存器

1)数据/一般寄存器:4个X(?)

不是做什么特别的功能,就是在程序运行的过程中需要做运算时,所借助的媒介,具体为:

  • EAX(Accumulator):被称为累加寄存器,用以进行算数运算和返回函数结果等。
  • EBX(Base):被称为基址寄存器,在内存寻址时(比如数组运算)用以存放基地址。
  • ECX(Counter):被称为记数寄存器,用以在循环过程中记数。
  • EDX(Data) :  被称为数据寄存器,常配合 eax 一起存放运算结果等数据。

2)索引寄存器:2个I(index)

用于字符串操作,字符串是一串有序的字符,所以在操作的时候肯定要有索引来标示处理的那个字符,具体为:

  • ESI(Source Index): 指向要处理的数据地址?
  • EDI(Destination Index):  指向存放处理结果的数据地址?

3)指针寄存器:  2个P(Pointer):

程序运行和函数调用时,都用到栈,不同的程序以及程序中不同的函数,都有各自的栈空间,那么怎么来维护不同的栈?,具体为:

  • ESP(Stack Pointer):  栈指针寄存器,其内存放着一个指针,永远指向当前栈的栈顶;
  • EBP(Base Pointer):基址指针寄存器,指向当前栈的栈底。
    wxy: 说到栈,都知道是用来存放函数中的一些局部变量等,即那些由程序临时分配存储的局部变量,而在系统栈空间的最上面一个栈帧,就是接下来要执行的函数(的栈帧),所以也常常说指向系统栈最上面一个栈帧的栈顶/底。

控制寄存器:1个P + 1个Flags 

控制专用的,属于司令部,指导程序接下来怎么运行的 

EIP(Instruction Pointer):处理器使用EIP来跟踪下一条要执行的指令,也称为程序计数寄存器

和EFLAGS。

wxy:有些地方提到寄存器都是ax,bx....ip等,也就是没有Extended这个单词,其实功能是一样的,只不过随着CPU位数的增长,

参考链接:

https://blog.csdn.net/chance_yin/article/details/8944038

http://ilinuxkernel.com/?p=1276

https://zhuanlan.zhihu.com/p/25892385

 

原文地址:https://www.cnblogs.com/shuiguizi/p/11651276.html

时间: 2024-07-31 08:28:47

Linux内存管理-预备篇(寄存器)的相关文章

linux内存管理之heap篇

文章来源——博客园绿色冰点 前几次我们分析了Linux系统中用户进程的4G虚存大致分为了几个部分,介绍了3G用户空间中数据段,代码段等静态区域的虚存管理,重点分析了栈的使用.这次我们来分析一下虚存使用中另一个重要部分--堆.前面的介绍中,我们知道编译器,操作系统担负着大量栈分配管理的工作.不论是静态分配的栈空间还是用户动态分配的栈空间,在函数返回的时候就自动释放了.堆的使用比之栈而言更为灵活,允许程序员动态的分配并释放,但也意味着,堆的使用需要程序员更为小心. 4.5 堆的内存管理 在学习"数据

启动期间的内存管理之初始化过程概述----Linux内存管理(九)

日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.7 X86 & arm gatieme LinuxDeviceDrivers Linux内存管理 在内存管理的上下文中, 初始化(initialization)可以有多种含义. 在许多CPU上, 必须显式设置适用于Linux内核的内存模型. 例如在x86_32上需要切换到保护模式, 然后内核才能检测到可用内存和寄存器. 而我们今天要讲的boot阶段就是系统初始化阶段使用的内存分配器. 1 前景回顾 1.1

linux内存管理---物理地址、线性地址、虚拟地址、逻辑地址之间的转换

linux内存管理---虚拟地址.逻辑地址.线性地址.物理地址的区别(一) 这篇文章中介绍了四个名词的概念,下面针对四个地址的转换进行分析 CPU将一个虚拟内存空间中的地址转换为物理地址,需要进行两步(如下图): 首先,将给定一个逻辑地址(其实是段内偏移量,这个一定要理解!!!),CPU要利用其段式内存管理单元,先将为个逻辑地址转换成一个线程地址, 其次,再利用其页式内存管理单元,转换为最终物理地址. 这样做两次转换,的确是非常麻烦而且没有必要的,因为直接可以把线性地址抽像给进程.之所以这样冗余

linux内存管理

一.Linux 进程在内存中的数据结构 一个可执行程序在存储(没有调入内存)时分为代码段,数据段,未初始化数据段三部分:    1) 代码段:存放CPU执行的机器指令.通常代码区是共享的,即其它执行程序可调用它.假如机器中有数个进程运行相同的一个程序,那么它们就可以使用同一个代码段.     2) 数据段:存放已初始化的全局变量.静态变量(包括全局和局部的).常量.static全局变量和static函数只能在当前文件中被调用.     3) 未初始化数据区(uninitializeddata s

Linux内存管理机制

一.首先大概了解一下计算机CPU.Cache.内存.硬盘之间的关系及区别. 1.  CPU也称为中央处理器(CPU,Central Processing Unit)是一块超大规模的集成电路, 是一台计算机的运算核心(Core)和控制核心( Control Unit).它的功能主要是解释计算机指令以及处理计算机软件中的数据.中央处理器主要由三核心部件组成,运算器.控制器和总线(BUS),运算器又主要由算术逻辑单元(ALU)和寄存器(RS)组成. 2.Cache即高速缓冲存储器,是位于CPU与主内存

linux内存管理浅析

[地址映射](图:左中)linux内核使用页式内存管理,应用程序给出的内存地址是虚拟地址,它需要经过若干级页表一级一级的变换,才变成真正的物理地址.想一下,地址映射还是一件很恐怖的事情.当访问一个由虚拟地址表示的内存空间时,需要先经过若干次的内存访问,得到每一级页表中用于转换的页表项(页表是存放在内存里面的),才能完成映射.也就是说,要实现一次内存访问,实际上内存被访问了N+1次(N=页表级数),并且还需要做N次加法运算.所以,地址映射必须要有硬件支持,mmu(内存管理单元)就是这个硬件.并且需

Linux内存管理1

1.前言 关于内存管理的系列文章主要是对陈莉君老师所讲述的内存管理知识的整理. 本文将主要以X86架构来介绍Linux内存管理的相关知识. 2. 内存寻址 内存寻址是操作系统设计的硬件基础之一 操作系统是横跨软件和硬件的桥梁 操作系统设计者必须在硬件相关代码和硬件无关代码之间划分清晰的界限,以便操作系统很容易的移植到不同的平台 内存寻址的不同时期 (1)石器时代---8位寻址:4004是4位寻址,8080是8位寻址,由一个主累加器(寄存器A)和6个次累加器(寄存器B,C,D,E,H和L),没有段

linux内存管理---虚拟地址、逻辑地址、线性地址、物理地址的区别(一)

分析linux内存管理机制,离不了上述几个概念,在介绍上述几个概念之前,先从<深入理解linux内核>这本书中摘抄几段关于上述名词的解释: 一.<深入理解linux内核>的解释 逻辑地址(Logical Address) 包含在机器语言指令中用来指定一个操作数或一条指令的地址(有点深奥).这种寻址方式在80x86著名的分段结构中表现得尤为具体,它促使windows程序员把程序分成若干段.每个逻辑地址都由一个段和偏移量组成,偏移量指明了从段开始的地方到实际地址之间的距离. 线性地址(

关于linux内存管理

 Linux的内存管理主要分为两部分:物理地址到虚拟地址的映射,内核内存分配管理(主要基于slab). 物理地址到虚拟地址之间的映射 1.概念 物理地址(physical address) 用于内存芯片级的单元寻址,与处理器和CPU连接的地址总线相相应.--这个概念应该是这几个概念中最好理解的一个,可是值得一提的是,尽管能够直接把物理地址理解成插在机器上那根内存本身,把内存看成一个从0字节一直到最大空量逐字节的编号的大数组,然后把这个数组叫做物理地址,可是其实,这仅仅是一个硬件提供给软件的抽像,