精华内容
下载资源
问答
  • 寄存器通俗解释
    千次阅读
    2018-07-09 18:46:28

    单片机程序必知的几个寄存器

    1.串口寄存器SBUF

    SBUF是指串行口中的两个缓冲寄存器,一个是发送寄存器,一个是接收寄存器,在物理结构上是完全独立的,但地址是重叠的。它们都是字节寻址的寄存器,字节地址均为99H

    串行发送数据时,CPUSBUF写入数据    SBUF=date; //发送数据

    串行接收数据时,CPUSBUF读出数据    date=SBUF; //接收数据

    2.TMOD:工作方式控制寄存器

    寄存器地址89H,不可位寻址。
    位序
    B7
    B6
    B5
    B4
    B3
    B2
    B1
    B0
    位符号
    GATE
    C/T
    M1
    M0
    GATE
    C/T
    M1
    M0
    GATE——门控位
    当=0时,以TR0(或TR1)状态决定定时器/计数器的启动或禁止
    当=1时,以TR0与INT0(或TR1与INT1)状态决定定时器/计数器的启动或禁止
    C/T=0 定时/计数工作方式选择位   0为定时器  1为计数器。

     M1M0——工作方式选择位
      M1M0=00     方式0:是13位计数结构的工作方式,其计数器由TH全部8位和TL的低5位构成。
    M1M0=01    方式1:是16位计数结构的工作方式,计数器由TH全部8位和TL全部8位构成。
    M1M0=10    方式2:自动装入8位计数器。
    M1M0=11    方式3:定时器/计数器0被拆成两个独立的8位计数器TL0和TH0。其中TL0既可以计数使用,又可以定时使用,定时器/计数器0的各控制位和引脚信号全归它使用。
    3.SCON控制寄存器
    .
    SCON寄存器各位定义
    D7
    D6
    D5
    D4
    D3
    D2
    D1
    D0
    SM0
    SM1
    SM2
    REN
    TB8
    RB8
    TI
    RI
    9FH
    9EH
    9DH
    9CH
    9BH
    9AH
    99H
    98H
    SM0、SM1
    ——串行口工作方式控制位
    SM0
    SM1
    工作方式
    功能
    波特率
    0
    0
    方式0
    8位同步移位寄存器
    晶振频率/12
    0
    1
    方式1
    10位UART
    可变
    1
    0
    方式2
    11位UART
    晶振频率/64或晶振频率/32
    1
    1
    方式3
    11位UART
    可变


    SM2

    ——多机通信控制位
    多机通信是工作于方式2和方式3,SM2位主要用于方式2和方式3。接收状态,当串行口工作于方式2或3,以及SM2=1时,只有当接收到第9位数据(RB8)为1时,才把接收到的前8位数据送入SBUF,且置位RI发出中断申请,否则会将接收到的数据放弃。当SM2=0时,就不管第9位数据是0还是1,都会将数据送入SBUF,并发出中断申请。工作于方式0时,SM2必须为0。

    REN

    ——允许接收位
    REN用于控制数据接收的允许和禁止,REN=1时,允许接收,REN=0时,禁止接收。

    TB8

    ——发送数据位8
    在方式2和方式3中,TB8是要发送的——即第9位数据位。在多机通信中同样亦要传输这一位,并且它代表传输的地址还是数据,TB8=0为数据,TB8=1时为地址。

    RB8

    ——接收数据位8
    在方式2和方式3中,RB8存放接收到的第9位数据,用以识别接收到的数据特征。

    TI

    ——发送中断标志位
    可寻址标志位。方式0时,发送完第8位数据后,由硬件置位,其它方式下,在发送或停止位之前由硬件置位,因此,TI=1表示帧发送结束,TI可由软件清“0”。

    RI

    ——接收中断标志位
    可寻址标志位。接收完第8位数据后,该位由硬件置位,在其他工作方式下,该位由硬件置位,RI=1表示帧接收完成。
    在串口中断处理时,TI,RI都需要软件清"0",硬件置位后不可能自动清0,此外,在进行缓冲区操作时,需要ES=0,以防止中断出现。
    4.AUXR辅助寄存器

    AUXR.0:S1BRS,如果为1那么串口1的波特率发生器为独立波特率发生器,否则为定时器1

    AUXR.1:EXTRAM,为1则可以使用内部扩展RAM

    AUXR.2:BRTx12,为1则独立波特率发生器不分频,否则12分频。

    AUXR.3:S2SMOD,为1串口2波特率加倍,否则不加倍

    AUXR.4:BRTR,为1则允许独立波特率允许,否则不允许。

    AUXR.5:UART_M0x6,为1则串口模式02分频,否则为12分频

    AUXR.6:T1x12,为1则定时器1不分频,否则12分频

    AUXR.7:T0x12,为1则定时器0不分频,否则12分频

    注意:12分频相当于传统的51单片机的速度

    注:

    AUXRAuxiliary Register(辅助寄存器)的缩写。

    AUXR寄存器不可位寻址。

    AUXR的第7位和第6位用得很多,分别用于设置定时器01是否12分频。因为是1T的单片机,为了兼容传统的8051

    若不设置则默认为0,即定时器12分频。

    例如:AUXR &= 0xBF; //定时器1时钟为Fosc/12,12T   1011 1111


    更多相关内容
  • 通俗易懂和你聊聊寄存器那些事(精美图文)

    千次阅读 多人点赞 2020-10-15 06:53:38
    下面我们就来介绍一下关于寄存器的相关内容。我们知道,寄存器是 CPU 内部的构造,它主要用于信息的存储。除此之外,CPU 内部还有运算器,负责处理数据;控制器控制其他组件;外部总线连接 CPU 和各种部件,进行数据...

    我把自己以往的文章汇总成为了 Github ,欢迎各位大佬 star
    https://github.com/crisxuan/bestJavaer

    下面我们就来介绍一下关于寄存器的相关内容。我们知道,寄存器是 CPU 内部的构造,它主要用于信息的存储。除此之外,CPU 内部还有运算器,负责处理数据;控制器控制其他组件;外部总线连接 CPU 和各种部件,进行数据传输;内部总线负责 CPU 内部各种组件的数据处理。

    那么对于我们所了解的汇编语言来说,我们的主要关注点就是 寄存器

    为什么会出现寄存器?因为我们知道,程序在内存中装载,由 CPU 来运行,CPU 的主要职责就是用来处理数据。那么这个过程势必涉及到从存储器中读取和写入数据,因为它涉及通过控制总线发送数据请求并进入存储器存储单元,通过同一通道获取数据,这个过程非常的繁琐并且会涉及到大量的内存占用,而且有一些常用的内存页存在,其实是没有必要的,因此出现了寄存器,存储在 CPU 内部。

    认识寄存器

    寄存器的官方叫法有很多,Wiki 上面的叫法是 Processing Register, 也可以称为 CPU Register,计算机中经常有一个东西多种叫法的情况,反正你知道都说的是寄存器就可以了。

    认识寄存器之前,我们首先先来看一下 CPU 内部的构造。

    assembly02 001

    CPU 从逻辑上可以分为 3 个模块,分别是控制单元、运算单元和存储单元,这三部分由 CPU 内部总线连接起来。

    几乎所有的冯·诺伊曼型计算机的 CPU,其工作都可以分为5个阶段:取指令、指令译码、执行指令、访存取数、结果写回

    • 取指令阶段是将内存中的指令读取到 CPU 中寄存器的过程,程序寄存器用于存储下一条指令所在的地址
    • 指令译码阶段,在取指令完成后,立马进入指令译码阶段,在指令译码阶段,指令译码器按照预定的指令格式,对取回的指令进行拆分和解释,识别区分出不同的指令类别以及各种获取操作数的方法。
    • 执行指令阶段,译码完成后,就需要执行这一条指令了,此阶段的任务是完成指令所规定的各种操作,具体实现指令的功能。
    • 访问取数阶段,根据指令的需要,有可能需要从内存中提取数据,此阶段的任务是:根据指令地址码,得到操作数在主存中的地址,并从主存中读取该操作数用于运算。
    • 结果写回阶段,作为最后一个阶段,结果写回(Write Back,WB)阶段把执行指令阶段的运行结果数据写回到 CPU 的内部寄存器中,以便被后续的指令快速地存取;

    计算机架构中的寄存器

    寄存器是一块速度非常快的计算机内存,下面是现代计算机中具有存储功能的部件比对,可以看到,寄存器的速度是最快的,同时也是造价最高昂的。

    assembly02 002

    我们以 intel 8086 处理器为例来进行探讨,8086 处理器是 x86 架构的前身。在 8086 后面又衍生出来了 8088 。

    在 8086 CPU 中,地址总线达到 20 根,因此最大寻址能力是 2^20 次幂也就是 1MB 的寻址能力,8088 也是如此。

    在 8086 架构中,所有的内部寄存器、内部以及外部总线都是 16 位宽,可以存储两个字节,因为是完全的 16 位微处理器。8086 处理器有 14 个寄存器,每个寄存器都有一个特有的名称,即

    AX,BX,CX,DX,SP,BP,SI,DI,IP,FLAG,CS,DS,SS,ES

    这 14 个寄存器有可能进行具体的划分,按照功能可以分为三种

    • 通用寄存器
    • 控制寄存器
    • 段寄存器

    下面我们分别介绍一下这几种寄存器

    通用寄存器

    通用寄存器主要有四种 ,即 AX、BX、CX、DX 同样的,这四个寄存器也是 16 位的,能存放两个字节。 AX、BX、CX、DX 这四个寄存器一般用来存放数据,也被称为 数据寄存器。它们的结构如下

    assembly02 003

    8086 CPU 的上一代寄存器是 8080 ,它是一类 8 位的 CPU,为了保证兼容性,8086 在 8080 上做了很小的修改,8086 中的通用寄存器 AX、BX、CX、DX 都可以独立使用两个 8 位寄存器来使用。

    在细节方面,AX、BX、CX、DX 可以再向下进行划分

    • AX(Accumulator Register) : 累加寄存器,它主要用于输入/输出和大规模的指令运算。
    • BX(Base Register):基址寄存器,用来存储基础访问地址
    • CX(Count Register):计数寄存器,CX 寄存器在迭代的操作中会循环计数
    • DX(data Register):数据寄存器,它也用于输入/输出操作。它还与 AX 寄存器以及 DX 一起使用,用于涉及大数值的乘法和除法运算。

    这四种寄存器可以分为上半部分和下半部分,用作八个 8 位数据寄存器

    • AX 寄存器可以分为两个独立的 8 位的 AH 和 AL 寄存器;
    • BX 寄存器可以分为两个独立的 8 位的 BH 和 BL 寄存器;
    • CX 寄存器可以分为两个独立的 8 位的 CH 和 CL 寄存器;
    • DX 寄存器可以分为两个独立的 8 位的 DH 和 DL 寄存器;

    除了上面 AX、BX、CX、DX 寄存器以外,其他寄存器均不可以分为两个独立的 8 位寄存器

    如下图所示。

    assembly02 004

    合起来就是

    assembly02 005

    AX 的低位(0 - 7)位构成了 AL 寄存器,高 8 位(8 - 15)位构成了 AH 寄存器。AH 和 AL 寄存器是可以使用的 8 位寄存器,其他同理。

    在认识了寄存器之后,我们通过一个示例来看一下数据的具体存储方式。

    比如数据 19 ,它在 16 位存储器中所存储的表示如下

    assembly02 006

    寄存器的存储方式是先存储低位,如果低位满足不了就存储高位,如果低位能够满足,高位用 0 补全,在其他低位能满足的情况下,其余位也用 0 补全。

    8086 CPU 可以一次存储两种类型的数据

    • 字节(byte): 一个字节由 8 bit 组成,这是一种恒定不变的存储方式
    • 字(word):字是由指令集或处理器硬件作为单元处理的固定大小的数据,对于 intel 来说,一个字长就是两个字节,字是计算机一个非常重要的特征,针对不同的指令集架构来说,计算机一次处理的数据也是不同的。也就是说,针对不同指令集的机器,一次能处理不用的字长,有字、双字(32位)、四字(64位)等。

    AX 寄存器

    我们上面探讨过,AX 的另外一个名字叫做累加寄存器或者简称为累加器,其可以分为 2 个独立的 8 位寄存器 AH 和 AL;在编写汇编程序中,AX 寄存器可以说是使用频率最高的寄存器。

    下面是几段汇编代码

    mov ax,20		/* 将 20 送入寄存器 AX*/
    mov ah,80   /* 将 80 送入寄存器 AH*/
    add ax,10	  /* 将寄存器 AX 中的数值加上 8 */
    

    这里注意下:上面代码中出现的是 ax、ah ,而注释中确是 AX、AH ,其实含义是一样的,不区分大小写。

    AX 相比于其他通用寄存器来说,有一点比较特殊,AX 具有一种特殊功能的使用,那就是使用 DIV 和 MUL 指令式使用。

    DIV 是 8086 CPU 中的除法指令。

    MUL 是 8086 CPU 中的乘法指令。

    BX 寄存器

    BX 被称为数据寄存器,即表明其能够暂存一般数据。同样为了适应以前的 8 位 CPU ,而可以将 BX 当做两个独立的 8 位寄存器使用,即有 BH 和 BL。BX 除了具有暂存数据的功能外,还用于 寻址,即寻找物理内存地址。BX 寄存器中存放的数据一般是用来作为偏移地址 使用的,因为偏移地址当然是在基址地址上的偏移了。偏移地址是在段寄存器中存储的,关于段寄存器的介绍,我们后面再说。

    CX 寄存器

    CX 也是数据寄存器,能够暂存一般性数据。同样为了适应以前的 8 位 CPU ,而可以将 CX 当做两个独立的 8 位寄存器使用,即有 CH 和 CL。除此之外,CX 也是有其专门的用途的,CX 中的 C 被翻译为 Counting 也就是计数器的功能。当在汇编指令中使用循环 LOOP 指令时,可以通过 CX 来指定需要循环的次数,每次执行循环 LOOP 时候,CPU 会做两件事

    • 一件事是计数器自动减 1

    • 还有一件就是判断 CX 中的值,如果 CX 中的值为 0 则会跳出循环,而继续执行循环下面的指令,

      当然如果 CX 中的值不为 0 ,则会继续执行循环中所指定的指令 。

    DX 寄存器

    DX 也是数据寄存器,能够暂存一般性数据。同样为了适应以前的 8 位 CPU ,DX 的用途其实在前面介绍 AX 寄存器时便已经有所介绍了,那就是支持 MUL 和 DIV 指令。同时也支持数值溢出等。

    ###段寄存器

    CPU 包含四个段寄存器,用作程序指令,数据或栈的基础位置。实际上,对 IBM PC 上所有内存的引用都包含一个段寄存器作为基本位置。

    段寄存器主要包含

    • CS(Code Segment) : 代码寄存器,程序代码的基础位置
    • DS(Data Segment): 数据寄存器,变量的基本位置
    • SS(Stack Segment): 栈寄存器,栈的基础位置
    • ES(Extra Segment): 其他寄存器,内存中变量的其他基本位置。

    索引寄存器

    索引寄存器主要包含段地址的偏移量,索引寄存器主要分为

    • BP(Base Pointer):基础指针,它是栈寄存器上的偏移量,用来定位栈上变量
    • SP(Stack Pointer): 栈指针,它是栈寄存器上的偏移量,用来定位栈顶
    • SI(Source Index): 变址寄存器,用来拷贝源字符串
    • DI(Destination Index): 目标变址寄存器,用来复制到目标字符串

    状态和控制寄存器

    就剩下两种寄存器还没聊了,这两种寄存器是指令指针寄存器和标志寄存器:

    • IP(Instruction Pointer): 指令指针寄存器,它是从 Code Segment 代码寄存器处的偏移来存储执行的下一条指令
    • FLAG : Flag 寄存器用于存储当前进程的状态,这些状态有
      • 位置 (Direction):用于数据块的传输方向,是向上传输还是向下传输
      • 中断标志位 (Interrupt) :1 - 允许;0 - 禁止
      • 陷入位 (Trap) :确定每条指令执行完成后,CPU 是否应该停止。1 - 开启,0 - 关闭
      • 进位 (Carry) : 设置最后一个无符号算术运算是否带有进位
      • 溢出 (Overflow) : 设置最后一个有符号运算是否溢出
      • 符号 (Sign) : 如果最后一次算术运算为负,则设置 1 =负,0 =正
      • 零位 (Zero) : 如果最后一次算术运算结果为零,1 = 零
      • 辅助进位 (Aux Carry) :用于第三位到第四位的进位
      • 奇偶校验 (Parity) : 用于奇偶校验

    物理地址

    我们大家都知道, CPU 访问内存时,需要知道访问内存的具体地址,内存单元是内存的基本单位,每一个内存单元在内存中都有唯一的地址,这个地址即是 物理地址。而 CPU 和内存之间的交互有三条总线,即数据总线、控制总线和地址总线。

    assembly008

    CPU 通过地址总线将物理地址送入存储器,那么 CPU 是如何形成的物理地址呢?这将是我们接下来的讨论重点。

    现在,我们先来讨论一下和 8086 CPU 有关的结构问题。

    cxuan 和你聊了这么久,你应该知道 8086 CPU 是 16 位的 CPU 了,那么,什么是 16 位的 CPU 呢?

    你可能大致听过这个回答,16 位 CPU 指的是 CPU 一次能处理的数据是 16 位的,能回答这个问题代表你的底层还不错,但是不够全面,其实,16 位的 CPU 指的是

    • CPU 内部的运算器一次最多能处理 16 位的数据

    运算器其实就是 ALU,运算控制单元,它是 CPU 内部的三大核心器件之一,主要负责数据的运算。

    • 寄存器的最大宽度为 16 位

    这个寄存器的最大宽度值得就是通用寄存器能处理的二进制数的最大位数

    • 寄存器和运算器之间的通路为 16 位

    这个指的是寄存器和运算器之间的总线,一次能传输 16 位的数据

    好了,现在你应该知道为什么叫做 16 位 CPU 了吧。

    在你知道上面这个问题的答案之后,我们下面就来聊一聊如何计算物理地址。

    8086 CPU 有 20 位地址总线,每一条总线都可以传输一位的地址,所以 8086 CPU 可以传送 20 位地址,也就是说,8086 CPU 可以达到 2^20 次幂的寻址能力,也就是 1MB。8086 CPU 又是 16 位的结构,从 8086 CPU 的结构看,它只能传输 16 位的地址,也就是 2^16 次幂也就是 64 KB,那么它如何达到 1MB 的寻址能力呢?

    原来,8086 CPU 的内部采用两个 16 位地址合成的方式来传输一个 20 位的物理地址,如下图所示

    assembly02 007

    叙述一下上图描述的过程

    CPU 中相关组件提供两个地址:段地址和偏移地址,这两个地址都是 16 位的,他们经由地址加法器变为 20 位的物理地址,这个地址即是输入输出控制电路传递给内存的物理地址,由此完成物理地址的转换。

    地址加法器采用 物理地址 = 段地址 * 16 + 偏移地址 的方法用段地址和偏移地址合成物理地址。

    下面是地址加法器的工作流程

    assembly02 008

    其实段地址 * 16 ,就是左移 4 位。在上面的叙述中,物理地址 = 段地址 * 16 + 偏移地址,其实就是基础地址 + 偏移地址 = 物理地址 寻址模式的一种具体实现方案。基础地址其实就等于段地址 * 16。

    你可能不太清楚 的概念,下面我们就来探讨一下。

    什么是段

    段这个概念经常出现在操作系统中,比如在内存管理中,操作系统会把不同的数据分成 来存储,比如 代码段、数据段、bss 段、rodata 段 等。

    但是这些的划分并不是内存干的,cxuan 告诉你是谁干的,这其实是幕后 Boss CPU 搞的,内存当作了声讨的对象。

    其实,内存没有进行分段,分段完全是由 CPU 搞的,上面聊过的通过基础地址 + 偏移地址 = 物理地址的方式给出内存单元的物理地址,使得我们可以分段管理 CPU。

    如图所示

    assembly02 009

    这是两个 16 KB 的程序分别被装载进内存的示意图,可以看到,这两个程序的段地址的大小都是 16380。

    这里需要注意一点, 8086 CPU 段地址的计算方式是段地址 * 16,所以,16 位的寻址能力是 2^16 次方,所以一个段的长度是 64 KB。

    段寄存器

    cxuan 在上面只是简单为你介绍了一下段寄存器的概念,介绍的有些浅,而且介绍段寄存器不介绍段也有不知庐山真面目的感觉,现在为你详细的介绍一下,相信看完上面的段的概念之后,段寄存器也是手到擒来。

    我们在合成物理地址的那张图提到了 相关部件 的概念,这个相关部件其实就是段寄存器,即 CS、DS、SS、ES 。8086 的 CPU 在访问内存时,由这四个寄存器提供内存单元的段地址。

    CS 寄存器

    要聊 CS 寄存器,那么 IP 寄存器是你绕不过去的曾经。CS 和 IP 都是 8086 CPU 非常重要的寄存器,它们指出了 CPU 当前需要读取指令的地址。

    CS 的全称是 Code Segment,即代码寄存器;而 IP 的全称是 Instruction Pointer ,即指令指针。现在知道这两个为什么一起出现了吧!

    在 8086 CPU 中,由 CS:IP 指向的内容当作指令执行。如下图所示

    assembly02 010

    说明一下上图

    在 CPU 内部,由 CS、IP 提供段地址,由加法器负责转换为物理地址,输入输出控制电路负责输入/输出数据,指令缓冲器负责缓冲指令,指令执行器负责执行指令。在内存中有一段连续存储的区域,区域内部存储的是机器码、外面是地址和汇编指令。

    上面这幅图的段地址和偏移地址分别是 2000 和 0000,当这两个地址进入地址加法器后,会由地址加法器负责将这两个地址转换为物理地址

    assembly02 011

    然后地址加法器负责将指令输送到输入输出控制电路中

    assembly02 012

    输入输出控制电路将 20 位的地址总线送到内存中。

    assembly02 013

    然后取出对应的数据,也就是 B8、23、01,图中的 B8、BB 都是操作数。

    assembly02 014

    控制输入/输出电路会将 B8 23 01 送入指令缓存器中。

    assembly02 015

    此时这个指令就已经具备执行条件,此时 IP 也就是指令指针会自动增加。我们上面说到 IP 其实就是从 Code Segment 也就是 CS 处偏移的地址,也就是偏移地址。它会知道下一个需要读取指令的地址,如下图所示

    assembly02 016

    在这之后,指令执行执行取出的 B8 23 01 这条指令。

    然后下面再把 2000 和 0003 送到地址加法器中再进行后续指令的读取。后面的指令读取过程和我们上面探讨的如出一辙,这里 cxuan 就不再赘述啦。

    通过对上面的描述,我们能总结一下 8086 CPU 的工作过程

    • 段寄存器提供段地址和偏移地址给地址加法器
    • 由地址加法器计算出物理地址通过输入输出控制电路将物理地址送到内存中
    • 提取物理地址对应的指令,经由控制电路取回并送到指令缓存器中
    • IP 继续指向下一条指令的地址,同时指令执行器执行指令缓冲器中的指令

    什么是 Code Segment

    Code Segment 即代码段,它就是我们上面聊到就是 CS 寄存器中存储的基础地址,也就是段地址,段地址其本质上就是一组内存单元的地址,例如上面的 mov ax,0123H 、mov bx, 0003H。我们可以将长度为 N 的一组代码,存放在一组连续地址、其实地址为 16 的倍数的内存单元中,我们可以认为,这段内存就是用来存放代码的。

    DS 寄存器

    CPU 在读写一个内存单元的时候,需要知道这个内存单元的地址。在 8086 CPU 中,有一个 DS 寄存器,通常用来存放访问数据的段地址。如果你想要读取一个 10000H 的数据,你可能会需要下面这段代码

    mov bx,10000H
    mov ds,bx
    mov a1,[0]
    

    上面这三条指令就把 10000H 读取到了 a1 中。

    在上面汇编代码中,mov 指令有两种传送方式

    • 一种是把数据直接送入寄存器
    • 一种是将一个寄存器的内容送入另一个寄存器

    但是不仅仅如此,mov 指令还具有下面这几种表达方式

    描述举例
    mov 寄存器,数据比如:mov ax,8
    mov 寄存器,寄存器比如:mov ax,bx
    mov 寄存器,内存单元比如:mov ax,[0]
    mov 内存单元,寄存器比如:mov[0], ax
    mov 段寄存器,寄存器比如:mov ds,ax

    栈我相信大部分小伙伴已经非常熟悉了,是一种具有特殊的访问方式的存储空间。它的特殊性就在于,先进入栈的元素,最后才出去,也就是我们常说的 先入后出

    它就像一个大的收纳箱,你可以往里面放相同类型的东西,比如书,最先放进收纳箱的书在最下面,最后放进收纳箱的书在最上面,如果你想拿书的话, 必须从最上面开始取,否则是无法取出最下面的书籍的。

    栈的数据结构就是这样,你把书籍压入收纳箱的操作叫做压入(push),你把书籍从收纳箱取出的操作叫做弹出(pop),它的模型图大概是这样

    assembly02 017

    入栈相当于是增加操作,出栈相当于是删除操作,只不过叫法不一样。栈和内存不同,它不需要指定元素的地址。它的大概使用如下

    // 压入数据
    Push(123);
    Push(456);
    Push(789);
    
    // 弹出数据
    j = Pop();
    k = Pop();
    l = Pop();
    

    在栈中,LIFO 方式表示栈的数组中所保存的最后面的数据(Last In)会被最先读取出来(First Out)。

    assembly02 018

    栈和 SS 寄存器

    下面我们就通过一段汇编代码来描述一下栈的压入弹出的过程

    8086 CPU 提供入栈和出栈指令,最基本的两个是 PUSH(入栈)POP(出栈)。比如 push ax 会把 ax 寄存器中的数据压入栈中,pop ax 表示从栈顶取出数据送入 ax 寄存器中。

    这里注意一点:8086 CPU 中的入栈和出栈都是以字为单位进行的。

    我这里首先有一个初始的栈,没有任何指令和数据。

    assembly02 019

    然后我们向栈中 push 数据后,栈中数据如下

    assembly02 020

    涉及的指令有

    mov ax,2345H
    push ax
    

    注意,数据会用两个单元存放,高地址单元存放高 8 位地址,低地址单元存放低 8 位。

    再向栈中 push 数据

    assembly02 021

    其中涉及的指令有

    mov bx,0132H
    push bx
    

    现在栈中有两条数据,现在我们执行出栈操作

    assembly02 022

    其中涉及的指令有

    pop ax
    /* ax = 0132H */
    

    再继续取出数据

    assembly02 023

    涉及的指令有

    pop bx
    /* bx = */
    

    完整的 push 和 pop 过程如下

    assembly02 024

    现在 cxuan 问你一个问题,我们上面描述的是 10000H ~ 1000FH 这段空间来作为 push 和 pop 指令的存取单元。但是,你怎么知道这个栈单元就是 10000H ~ 1000FH 呢?也就是说,你如何选择指定的栈单元进行存取?

    事实上,8086 CPU 有一组关于栈的寄存器 SSSP。SS 是段寄存器,它存储的是栈的基础位置,也就是栈顶的位置,而 SP 是栈指针,它存储的是偏移地址。在任意时刻,SS:SP 都指向栈顶元素。push 和 pop 指令执行时,CPU 从 SS 和 SP 中得到栈顶的地址。

    现在,我们可以完整的描述一下 push 和 pop 过程了,下面 cxuan 就给你推导一下这个过程。

    assembly02 025

    上面这个过程主要涉及到的关键变化如下。

    当使用 PUSH 指令向栈中压入 1 个字节单元时,SP = SP - 1;即栈顶元素会发生变化;

    而当使用 PUSH 指令向栈中压入 2 个字节的字单元时,SP = SP – 2 ;即栈顶元素也要发生变化;

    当使用 POP 指令从栈中弹出 1 个字节单元时, SP = SP + 1;即栈顶元素会发生变化;

    当使用 POP 指令从栈中弹出 2 个字节单元的字单元时, SP = SP + 2 ;即栈顶元素会发生变化;

    栈顶越界问题

    现在我们知道,8086 CPU 可以使用 SS 和 SP 指示栈顶的地址,并且提供 PUSH 和 POP 指令实现入栈和出栈,所以,你现在知道了如何能够找到栈顶位置,但是你如何能保证栈顶的位置不会越界呢?栈顶越界会产生什么影响呢?

    比如如下是一个栈顶越界的示意图

    assembly02 026

    第一开始,SS:SP 寄存器指向了栈顶,然后向栈空间 push 一定数量的元素后,SS:SP 位于栈空间顶部,此时再向栈空间内部 push 元素,就会出现栈顶越界问题。

    栈顶越界是危险的,因为我们既然将一块区域空间安排为栈,那么在栈空间外部也可能存放了其他指令和数据,这些指令和数据有可能是其他程序的,所以如此操作会让计算机懵逼

    我们希望 8086 CPU 能自己解决问题,毕竟 8086 CPU 已经是个成熟的 CPU 了,要学会自己解决问题了。

    assembly02 027

    然鹅(故意的),这对于 8086 CPU 来说,这可能是它一辈子的 夙愿 了,真实情况是,8086 CPU 不会保证栈顶越界问题,也就是说 8086 CPU 只会告诉你栈顶在哪,并不会知道栈空间有多大,所以需要程序员自己手动去保证。。。

    另外,我输出了 六本 PDF,已免费提供下载,如下所示

    链接: https://pan.baidu.com/s/1mYAeS9hIhdMFh2rF3FDk0A 密码: p9rs

    展开全文
  • 控制寄存器是CPU中一组相当重要的寄存器,我们知道eflags寄存器记录了当前运行线程的一系列关键信息。 那CPU运行过程中自身的一些关键信息保存在哪里呢?答案是控制寄存器! 32位CPU总共有cr0-cr4共5个控制...

    控制寄存器是CPU中一组相当重要的寄存器,我们知道eflags寄存器记录了当前运行线程的一系列关键信息。

    那CPU运行过程中自身的一些关键信息保存在哪里呢?答案是控制寄存器!

    一口气看完45个寄存器,CPU核心技术大揭秘

     

    32位CPU总共有cr0-cr4共5个控制寄存器,64位增加了cr8。他们各自有不同的功能,但都存储了CPU工作时的重要信息:

    cr0: 存储了CPU控制标记和工作状态

    cr1: 保留未使用

    cr2: 页错误出现时保存导致出错的地址

    cr3: 存储了当前进程的虚拟地址空间的重要信息——页目录地址

    cr4: 也存储了CPU工作相关以及当前人任务的一些信息

    cr8: 64位新增扩展使用

    其中,CR0尤其重要,它包含了太多重要的CPU信息,值得单独关注一下:

    一口气看完45个寄存器,CPU核心技术大揭秘

     

    一些重要的标记位含义如下:

    PG: 是否启用内存分页

    AM: 是否启用内存对齐自动检查

    WP: 是否开启内存写保护,若开启,对只读页面尝试写入时将触发异常,这一机制常常被用来实现写时复制功能

    PE: 是否开启保护模式

    除了CR0,另一个值得关注的寄存器是CR3,它保存了当前进程所使用的虚拟地址空间的页目录地址,可以说是整个虚拟地址翻译中的顶级指挥棒,在进程空间切换的时候,CR3也将同步切换。

    展开全文
  • 寄存器与存储器物理区别

    千次阅读 多人点赞 2018-11-07 14:14:25
    从根本上讲,寄存器与存储器RAM的元件不一样???? memory is equivalent to a lot of registers. 寄存器存在于CPU中,速度...Mike Ash写了一篇很好的解释,非常通俗地回答了这个问题,有助于加深对硬件的理解。...

    从根本上讲,寄存器与存储器RAM的元件不一样????

    memory is equivalent to a lot of registers.

    寄存器存在于CPU中,速度很快,但是所占面积大,数目有限;
    存储器就是内存,速度稍慢,所占面积小,但数量很大;
    计算机做运算时,必须将数据读入寄存器才能运算。

     

    Mike Ash写了一篇很好的解释,非常通俗地回答了这个问题,有助于加深对硬件的理解。下面就是我的简单翻译。

    原因一:距离不同

    距离不是主要因素,但是最好懂,所以放在最前面说。内存离CPU比较远,所以要耗费更长的时间读取。

    以3GHz的CPU为例,电流每秒钟可以振荡30亿次,每次耗时大约为0.33纳秒。光在1纳秒的时间内,可以前进30厘米。也就是说,在CPU的一个时钟周期内,光可以前进10厘米。因此,如果内存距离CPU超过5厘米,就不可能在一个时钟周期内完成数据的读取,这还没有考虑硬件的限制和电流实际上达不到光速。相比之下,寄存器在CPU内部,当然读起来会快一点。

    距离对于桌面电脑影响很大,对于手机影响就要小得多。手机CPU的时钟频率比较慢(iPhone 5s为1.3GHz),而且手机的内存紧挨着CPU。

    原因二:硬件设计不同

    苹果公司新推出的iPhone 5s,CPU是A7,寄存器有6000多位(31个64位寄存器,加上32个128位寄存器)。而iPhone 5s的内存是1GB,约为80亿位(bit)。这意味着,高性能、高成本、高耗电的设计可以用在寄存器上,反正只有6000多位,而不能用在内存上。因为每个位的成本和能耗只要增加一点点,就会被放大80亿倍。

    事实上确实如此,内存的设计相对简单,每个位就是一个电容和一个晶体管,而寄存器的设计则完全不同,多出好几个电子元件。并且通电以后,寄存器的晶体管一直有电,而内存的晶体管只有用到的才有电,没用到的就没电,这样有利于省电。这些设计上的因素,决定了寄存器比内存读取速度更快。

    原因三:工作方式不同

    寄存器的工作方式很简单,只有两步:(1)找到相关的位,(2)读取这些位。

    内存的工作方式就要复杂得多

     

    寄存器(以RS锁存器例)

    flip-flop 触发器

    latch 锁存器

    一般寄存器是指由基本的RS触发器结构衍生出来的D触发,就是一些与非门构成的结构,这个在数电里面大家都看过;

     

     

     

    单个触发器定义:https://baike.baidu.com/item/触发器/193146

    触发器的电路图由逻辑门组合而成,其结构均由R-S锁存器派生。触发器可以处理输入、输出信号和时钟频率之间的相互影响。

    在R-S锁存器的前面加一个由两个与门和一个非门构成的附加电路,则构成D触发器。

    当时钟脉冲CP为1时,读入输入端D的数据并传至输出端;当CP为0时,根据与门“只要有一个输入端为0

    则输出为0”的特性,输入端D的数据被与门屏蔽了,无法到达输出端,不管输入D怎样变化,Q端输出值都保持不变,只有等到下一个CP高电平到来时,才会把当前的D值送出。这样就实现了延迟输出即暂时保存的功能。从电路的动作可以看出,时钟输入端起到控制的作用,CP为1时,能触发后面的锁存器把D的值暂时锁存起来,这也正是触发器名词中“触发”的含义,这正是触发器与锁存器的联系与区别:触发器利用了锁存器的保存原理,但是加上了触发功能,可以控制保存的时间。

    RS锁存器电路:

     

    基础知识反相器

    反相器inverter:

    当输入Vin=0 V时,晶体管截止,集电极开路,Vout=5 V;

    当输入Vin=5 V时,晶体管饱和,饱和导通,Vout=0 V

    触发器的基本物理组成:电阻、电容、二极管、三极管

    下图是由4个三极管组成的4位寄存器,它的原理是:用晶体管导通状态(0011)或集电极电压(1100)记录输入电压(0011),这个寄存器能寄存15种状态(0000~1111).

     

    存储器

    不同的存储位置,程序指令执行周期不同。

    硬件寄存器和程序寄存器(4.2.5节)

    数电第七章:半导体存储器

    ROM和PROM:例由二极管、MOS管构成。非易失性存储,存储于ROM中的程序称固件firmware。

    例:由二极管组成的8个存储单元(每个单元4bit)的ROM。

    图1:8个地址address对应的存储内容word

    图2:用二极管实现图1逻辑。8条地址线,4条数据线。

    图3:8个地址用3个二进制位编码,实现整个电路都用二进制表示,programmable ROM

     

    EPROM,erasable,紫外线擦写,由MOSFET管构成?

    EPROM,electrically erasable,电擦除

    下图的ROM还加入了EN使能,除了地址和数据,还有第三种控制。

    RAM则有自己的工艺。

    静态statistic SRAM:靠VDD供电,不动。图a,Q1Q2控制,Q3Q4寄存,形成一个latch。

    动态dynamic DRAM。靠电容供电,电容会放电,需反复快速充电,动态。

    下图分别是静态和动态,但是功能一样,锁存1bit???

    DRAM比SRAM电路简单,占用面积少,但是DRAM刷新电容电路复杂,从控制电路看,SRAM简单。

    SRAM的每个位存储在一个双稳态存储器单元里,每个单元由6个MOS管实现”

    DRAM每个位由一个充电电容和一个访问晶体管组成”

     

     

    单片机的寄存器:“每个寄存器有分配的唯一地址”

    为什么寄存器也有地址?寄存器也属于内存?x86中的寄存器有地址吗?

     

     

    这个图???物理部分需要分隔开??

    DOS内存管理:为物理内存分配地址??

     

    “主存是x86CPU外的存储区域,堆栈是在主存中开辟的一片数据存储区”

    x86芯片的寄存器都有自己的名字(有相应的机器代码约定,寄存器标识符),所以不需要地址???

    程序寄存器:

    芯片的寿命一般是多长 ?

    http://3g.163.com/dy/article/DHRHTT420511UFN2.html

    如果说是SSD上用的闪存芯片,那就有相对有限的寿命了,闪存芯片主要分为SLC、MLC和TLC三种,SLC寿命最长,速度最快,但是成本最高,TLC则相反。闪存的寿命磨损就在于闪存单元的写入-擦除,一般来说,SLC闪存可进行100000次写入-擦除循环,MLC可进行10000次左右。不要觉得可怕,得益于越来越先进的主控芯片,日常使用下正常的闪存芯片没那么容易用坏,即使是TLC闪存,寿命达到8年以上也没有问题,使用几年后一般都会掉速,不过实际影响并不大。其实相比闪存芯片,SSD上的主控反而更有可能先坏掉。所以我们不用太在意闪存芯片的寿命,一般在你换下一个SSD或者手机时,它就直接淘汰掉了。不过对于7*24小时工作的服务器来说,非常不建议用SSD,因为在这种高强度工作环境下的闪存芯片寿命会大打折扣,即使是机械硬盘,用个两三年挂掉的几率也很高。

    至于电脑上的内存芯片(RAM),由于其电容存储机制,只要是正常没有缺陷的芯片,寿命非常长,要不然绝大多数内存条都是终身保,只要不是不当超频,静电损坏,人为破坏,正常的内存寿命几乎不用担心。

     

    可编程逻辑技术(FPGA/CPLD)在存储中的应用

     

    存储器

    T:transistor晶体管 C:Capacitance电容

    DRAM:dynamic random access memory动态存储器。一个电容;一个晶体管。存储原理:动态MOS存储单元利用MOS管栅极电容来存储信息,但由于栅极电容的容量很小,而漏电流又不可能绝对等于0,所以电荷保存的时间有限。为了避免存储信息的丢失,必须定时地给电容补充漏掉的电荷。通常把这种操作称为“刷新”或“再生”,该时间必须小于栅极电容自然保持信息的时间(小于2ms),因此DRAM内部要有外围刷新控制电路,其操作也比SRAM复杂。尽管如此,由于DRAM存储单元的结构能做得非常简单,所用元件少,功耗低,已成为大容量RAM的主流产品。

    SRAM:static静态存储器。存储原理:由触发器存储数据。有锁存器。单元结构:六管NMOS或OS构成。速度快、使用简单、不需刷新、静态功耗极低;常用作Cache。●缺点:元件数多、集成度低、运行功耗大。●常用的SRAM集成芯片:6116(2K×8位),6264(8K×8位),62256(32K×8位),2114(1K×4位)

    ROM:

    掩膜ROM:数据通过掩膜方式写入。掩膜:烧断每个单元内与外部相连的熔丝。

    EEPROM:数据通过紫外线照射或注入隧穿电流方式写入。

     

     

    参考文献:

    1、数字电子技术基础

    2、《深入理解计算机系统》第三版,第六章

    3、《DOS原理与结构》

    4、《[80X86汇编语言程序设计].王元珍.文字版》

    5、《Dsp-Digital-Signal-Processing-With-Fpga》

    6、《CMOS数字集成电路:分析与设计  第3版》第十章 半导体存储

    7、《Digital Computer Electronics-McGraw-Hill (1993)》第九章 memories

    展开全文
  • 【单片机基础】(二)寄存器

    千次阅读 2021-02-01 16:34:58
    单片机内部有大量寄存器寄存器是一种能够存储数据的电路, 由触发器构成。 1.触发器 触发器是一种具有记忆存储功能的电路, 由门电路组成。 常见的触发器包括: RS 触发器、 D 触发器和 JK触发器等, 其中D触发器...
  • STM32 GPIO寄存器配置操作解释

    千次阅读 2022-02-11 16:41:05
    11位低位 总的来说可以如下图所示理解,Px8到Px15是对应CRH的高位 以上关于GPIO进行寄存器配置的操作来源:stm32 关于GPIO寄存器操作_Joker2019.-CSDN博客 理解上述寄存器后,下面是比较简单通俗的做法:配置PC5 1....
  • 工程中的寄存器一般按计算机中字节的位数设计,所以一般有8位寄存器、16位寄存器等。 对寄存器中的触发器只要求它们具有置1、置0的功能即可,因而无论是用同步RS结构触发器,还是用主从结构或边沿触发结构的触发器...
  • 常用寄存器说明
  • 寄存器和内存的区别

    千次阅读 2021-07-28 11:04:02
    寄存器和内存的区别1、寄存器是中央处理器内的组成部份。它跟CPU有关。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和位址。在中央处理器的控制部件中,包含的寄存器有指令寄存器(IR)和程序计数器...
  • 通俗点来说就是寻找数据。cpu要读写一个内存单元时,必须要知晓这个内存单元在哪,因此便可以通过ds(数据段寄存器)和偏移地址两个参数,来确定这个内存单元在哪。 一、访问内存中的数据的方式 方式一:段地址(ds):...
  • JAVA虚拟机的通俗解释

    2021-03-01 08:42:56
    JAVA虚拟机的百度解释如下。虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java虚拟机屏蔽...
  • 由于Lua采用了寄存器模式,而ILRunTime在过去是没有支持寄存器模式的,所以在比较时都会说ILRunTime的计算性能比起Lua要略微差一点 但是现在ILRunTime已经增加了寄存器模式,接下来我们就来看一看什么是ILRunTime的...
  • day04.3-标志寄存器

    2022-02-12 13:07:19
    一、标志寄存器总览>二、标志寄存器常用的标志>三、CF最高位进位与OF溢出区别
  • modbus协议中的寄存器理解

    万次阅读 多人点赞 2019-09-11 14:46:37
    modbus协议中的寄存器理解 对modbus中常用功能码寄存器的理解 最近有用到modbus协议,就把之前原来收集的资料全都拿出来又复习了一遍。发现以前了解的也忘了差不多了。所以这次理解了赶紧做个总结,省的下次再忘记...
  • 最近有用到modbus协议,就把之前原来收集的资料全都拿出来又...0x01: 读线圈寄存器 0x02: 读离散输入寄存器 0x03: 读保持寄存器 0x04: 读输入寄存器 0x05: 写单个线圈寄存器 0x06: 写单个保持寄存器 0x0f...
  • DDS原理的通俗解释

    千次阅读 2020-09-20 11:51:46
    DDS原理的通俗解释 DDS DDS是直接数字式频率合成器(Direct Digital Synthesizer)的英文缩写,是一项关键的数字化技术。与传统的频率合成器相比,DDS具有低成本、低功耗、高分辨率和快速转换时间等优点,广泛使用...
  • 通俗解释什么是指令集

    千次阅读 2021-06-12 15:28:22
    2、汇编语言 机器语言的问题在于人类要传递给计算机任何信息都必须以0和1的组合序列表达,不符合人类的沟通习惯,因此有了助记符的概念并在这个基础上产生了汇编语言,通俗来说我们需要将1+2这种信息表达为计算机可...
  • X86汇编常见的寄存器

    千次阅读 2019-08-03 11:52:39
    X86汇编常见的寄存器 4个数据寄存器(EAX、EBX、ECX和EDX) 2个变址和指针寄存器(ESI和EDI) 2个指针寄存器(ESP和EBP) 6个段寄存器(ES、CS、SS、DS、FS和GS) 1个指令指针寄存器(EIP) 1个标志寄存器(EFlags) AH&AL...
  • 两个二进制数(不是二进制则转化为二进制),按对应位置两两组合进行比较。 按位与:相同则保留该值,不同取0; 按位或:相同则保留该值,不同取1; eg: 0011 &= 0001 --> 0001 eg: 0011 |= 0001 -->...
  • 下面我尽量用通俗的语言来试着解释。计算机由CPU、内存、硬盘、显示器和键盘等部件组成。计算机软件平时在不工作时则是存放在硬盘里的,计算机开机之后,需要用到的软件就被调入内存来执行。无论在硬盘还是在内存里...
  • 首先,FSMC是什么,FSMC我自己的理解就是,一个衔接CPU与外部存储的桥梁,它的功能呢就是你往相应的地址里写数据时候,你不需用软件来模拟外部存储芯片的读写时序,而只需配置好FSMC相关的时序寄存器,配置好相关...
  •   条件码(condition code)寄存器,是CPU维护的一组单个位的用于描述最近的算术或逻辑操作的状态属性,条件分支指令可以检测这些寄存器的值来确定转移方向,最常用的条件码有:   CF:进位标志。最近的操作使最高...
  • CPU/寄存器/内存  因为要了解多线程,自然少不了一些硬件知识的科普,我没有系统学习过硬件知识,仅仅是从书上以及网络上看来的,如果有错误请指出来。  CPU,全名Central Processing Unit(中央处理器)。这是...
  • 在AHCI协议中Port Register中有如下几个寄存器,我们这里主要关注PxSSTS和PxSERR 2. 什么是SCR寄存器 参考AHCI协议14.1章节 Sata host适配器包括了一个额外的寄存器块,这些寄存器是分离的独立的,映射了ATA ...
  • FSMC原理通俗解释

    万次阅读 多人点赞 2019-04-01 00:48:00
    首先,FSMC是什么,FSMC我自己的理解就是,一个衔接CPU与外部存储的桥梁,它的功能呢就是你往相应的地址里写数据时候,你不需用软件来模拟外部存储芯片的读写时序,而只需配置好FSMC相关的时序寄存器,配置好相关...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,370
精华内容 2,948
热门标签
关键字:

寄存器通俗解释