精华内容
下载资源
问答
  • 寄存器的工作方式
    千次阅读
    2021-11-22 12:02:55

    UVM 寄存器访问方式


    利用寄存器模型,我们可以更方便地对寄存器做操作。我们分成两种访问寄存器的方式,即前门访问(front-door)和后门访问(back-door)。

    • 前门访问,顾名思义指的是在寄存器模型上做的读写操作,最终会通过总线UVC来实现总线上的物理时序访问,因此是真实的物理操作。
    • 后门访问,值得是利用UVM DPI(uvm_hdl_read()、uvm_hdl_deposit()),将寄存器的操作直接作用到DUT内的寄存器变量,而不通过物理总线访问。

    前门访问

    接下来前门访问的示例中的sequence继承于uvm_reg_sequence。uvm_reg_sequence除了具备一般uvm_sequence的预定义方法外,还具有跟寄存器操作相关的方法。
    在对寄存器操作的示例中,用户可以看到两种方式:

    • 第一种即uvm_reg::read()/write()。在传递时,用户需要注意将参数path指定为UVM_FRONTDOOR。uvm_reg::read()/write()方法可传入的参数较多,除了status和value两个参数需要传入,其它参数如果不指定,可采用默认值。
    • 第二种即uvm_reg_sequence::read_reg()/write_reg()。在使用时,也需要将path指定为UVM_FRONTDOOR。

    前门访问示例

    class mcdf_example_seq extends uvm_reg_sequence;
    	mcdf_rgm rgm;
    	`uvm_object_utils(mcdf_example_seq)
    	`uvm_declare_p_sequencer(mcdf_bus_sequencer)
    	...
    	task body();
    		uvm_status_e status;
    		uvm_reg_data_t data;
    		if(!uvm_config_db#(mcdf_rgm)::get(null,get_full_name(),"rgm",rgm))begin
    			`uvm_error("GETRGM","no top-down RGM handle is assigned")
    		end
    		//register model access write()/read()
    		rgm.chnl0_ctrl_reg.read(status,data,UVM_FRONTDOOR, .paraent(this));
    		rgm.chnl0_ctrl_reg.write(status,'h11,UVM_FRONTDOOR, .paraent(this));
    		rgm.chnl2_ctrl_reg.read(status,data,UVM_FRONTDOOR, .paraent(this));
    		//pre-defined methods access
    		read_reg(rgm.chnl1_ctrl_reg,status,data,UVM_FRONTDOOR);
    		write_reg(rgm.chnl1_ctrl_reg,status,'h22,UVM_FRONTDOOR);
    		read_reg(rgm.chnl1_ctrl_reg,status,data,UVM_FRONTDOOR);
    	endtask
    endclass
    

    uvm_reg有自己的write或read函数
    uvm_reg_sequence自定义的函数为read_reg和write_reg

    后门访问

    在进行后门访问时,用户首先需要确保寄存器模型在建立时,是否将各个寄存器映射到了DUT一侧的HDL路径。下面的例码即实现了寄存器模型与DUT各个寄存器的路径映射:

    class mcdf_rgm extends uvm_reg_block;
    ...//寄存器成员和map声明
    	virtual function build();
    		...//寄存器成员和map创建
    		//关联寄存器模型和HDL
    		add_hdl_path("reg_backdoor_access.dut");
    			chnl0_ctrl_reg.add_hdl_path_slice($sformatf("regs[%0d]",`SLV0_RW_REG),0,32);
    			chnl1_ctrl_reg.add_hdl_path_slice($sformatf("regs[%0d]",`SLV1_RW_REG),0,32);
    			chnl2_ctrl_reg.add_hdl_path_slice($sformatf("regs[%0d]",`SLV2_RW_REG),0,32);
    			chnl0_stat_reg.add_hdl_path_slice($sformatf("regs[%0d]",`SLV0_R_REG),0,32);
    			chnl1_stat_reg.add_hdl_path_slice($sformatf("regs[%0d]",`SLV1_R_REG),0,32);
    			chnl2_stat_reg.add_hdl_path_slice($sformatf("regs[%0d]",`SLV2_R_REG),0,32);
    		lock_model();	
    	endfunction
    endclass
    

    示例中通过uvm_reg_block::add_hdl_path(),将寄存器模型关联到了DUT一端,而通过uvm_reg::add_hdl_path_slice完成了将寄存器模型各个寄存器成员与HDL一侧的地址映射。

    另外,寄存器模型build()函数最后以lock_model()结尾,该函数的功能是结束地址映射关系,并且保证模型不会被其它用户修改。

    在寄存器模型中完成了HDL路径映射后,我们才可以利用uvm_reg或者uvm_reg_sequence自带的方法进行后门访问,后门访问也有几类方法提供:

    • uvm_reg::read()/write(),在调用该方法时需要注明UVM_BACKDOOR的访问方式。
    • uvm_reg_sequence::read_reg()/write_reg(),在使用时也需要注明UVM_BACKDOOR的访问方式。
    • 另外,uvm_reg::peek()/poke()两个方法,也分别对应了读取寄存器(peek)和修改寄存器(poke)两种操作,而用户无需指定访问方式为UVM_BACKDOOR,因为这两个方法本身就只针对于后门访问。

    后门访问示例

    class mcdf_example_seq extends uvm_reg_sequence;
    	mcdf_rgm rgm;
    	`uvm_object_utils(mcdf_example_seq)
    	`uvm_declare_p_sequencer(mcdf_bus_sequencer)
    	...
    	task body();
    		uvm_status_e status;
    		uvm_reg_data_t data;
    		if(!uvm_config_db#(mcdf_rgm)::get(null,get_full_name(),"rgm",rgm))begin
    			`uvm_error("GETVIF","no top-down RGM handle is assigned")
    		end
    		//register model access write()/read()
    		rgm.chnl0_ctrl_reg.read(status,data,UVM_BACKDOOR,.parent(this));
    		rgm.chnl0_ctrl_reg.write(status,'h11,UVM_BACKDOOR,.parent(this));
    		rgm.chnl0_ctrl_reg.read(status,data,UVM_BACKDOOR,.parent(this));
    		//register model access poke()/peek()
    		rgm.chnl1_ctrl_reg.peek(status,data,.parent(this));
    		rgm.chnl1_ctrl_reg.poke(status,'h22,.parent(this));
    		rgm.chnl1_ctrl_reg.peek(status,data,.parent(this));
    		//pre-defined methods read_reg()/write_reg()
    		read_reg(rgm.chnl2_ctrl_reg,status,data,UVM_BACKDOOR);
    		write_reg(rgm.chnl2_ctrl_reg,status,'h22,UVM_BACKDOOR);
    		read_reg(rgm.chnl2_ctrl_reg,status,data,UVM_BACKDOOR);
    		//pre-defined methods peek_reg()/poke_reg()
    		peek_reg(rgm.chnl2_ctrl_reg,status,data);
    		poke_reg(rgm.chnl2_ctrl_reg,status,'h22);
    		peek_reg(rgm.chnl2_ctrl_reg,status,data);
    	endtask
    endclass
    

    前门访问与后门访问的比较

    在这里插入图片描述

    • 从上面的差别可以看出,后门访问角前门访问更便捷更快一些,但如果单纯依赖后门访问也不能称之为“正道”。
    • 实际上,利用寄存器模型的前门访问和后门访问混合方式,对寄存器验证的完备性更有帮助。

    前门与后门的混合应用

    下面给出一些实际用于的场景

    • 通过前门访问的方式,先验证寄存器访问的物理通路工作正常,并且有专门的寄存器测试的前门访问用例,来遍历所有的寄存器。在前门访问被验证充分的前提下,可以在后续测试中使用后门访问来节省访问多个寄存器的时间。
    • 如果DUT实现了一些特殊寄存器,例如只能写一次的寄存器等,我们就建议用物理方法去访问以确保反映真实的硬件行为。
    • 寄存器随机设置的精髓不在于随机可设置的域值,而是为了考虑日常不可预期的场景,先通过后门访问随机化整个寄存器列表(在一定的随机限制下),随后再通过前门访问来配置寄存器。这么做的好处在于,不再只是通过设置复位之后的寄存器这种更有确定性的场景,而是通过让测试序列一开始的寄存器值都随机化来模拟无法预期的硬件配置前场景,而在稍后设置了必要的寄存器之后,再来看是否会有意想不到的边界情况发生。
    • 有的时候,即便通过先写再读的方式来测试一个寄存器,也可能存在地址不匹配的情况。譬如寄存器A地址本应该0x10,寄存器B地址本应该为0x20;而在硬件实现中,寄存器A对应的地址为0x20,寄存器B对应的地址为0x10。像这种错误,即便通过先写再读的方式也无法有效测试出来,那么不妨在通过前门配置寄存器A之后,再通过后门访问来判断HDL地址映射的寄存器A变量值是否改变,最后通过前门访问来读取寄存器A的值。上述的方式是在前门测试的基础上又加入了中途的后门访问和数值比较,可以发现地址映射到错误寄存器的问题。
    • 对于一些状态寄存器,有一些时候外界的激励条件修改会依赖这些状态寄存器,并且在时序上的要求也可能很严格。例如,上面MCDF的寄存器中有一组状态寄存器表示各个channel中FIFO的余量,而channel中FIFO的余量对于激励驱动的行为也很重要。无论是前门访问还是后门访问,都可能无法第一时间反映FIFO当前时刻的余量。因此对于要求更严格的测试场景,除了需要前门和后门来访问寄存器,也需要映射一些重要的信号来反映更即时的信息。
      前门写,后门读。后门写、前门读。

    关注作者

    • 自述
      作者是一位中科大数字设计专业的研究生,水平有限,如有错误,请大家指正,想要与大家一同进步。
    • 经历
      曾获得国家奖学金,“高教社杯”数学建模国家二等奖等
    • 陆续更新:
      1.与UVM验证相关的system verilog后续内容;
      2.与verilog数字设计相关的一些基础模块设计,例如FIFO,UART,I2C等的书写。
      3.保研与竞赛经历等
    • 微信公众号
      欢迎大家关注公众号“数字IC小白的日常修炼”,期待与大家一同仗剑遨游数字IC世界。`
    更多相关内容
  • 串口工作方式寄存器1

    2022-08-08 19:28:00
    串口工作方式寄存器SCON,位D7D6D5D4D3D2D1D0功能SM0SM1SM2RENTB8RB8TIRIRI:接收中断标志位,数据接收结束时,标志位会自动
  • 多扇出网线会造成网络线延时大,从而降低...解决的办法是采用复制寄存器方式,如下图所示。复制寄存器后,将有效地减少寄存器的扇出数量,从而改善设计的性能。  图 复制寄存器可提高器件的工作速度 来源:ks99
  • 本文内容: 一、处理器架构 二、内存机制分段机制内存访问通用寄存器AX 寄存器BX 寄存器CX 寄存器DX 寄存器指针寄存器 BP变址寄存器 SI/DI其他寄存器CS 寄存器 和 IP 寄存器SS 寄存器和 SP 寄存器DS 寄存器和 ES ...

    系列文章

    x86 - CPU架构/寄存器详解 (一)x86、8086、i386、IA-32 是什么?
    x86 - CPU架构/寄存器详解 (二) 实模式(8086模式)
    x86 - CPU架构/寄存器详解 (三) 保护模式
    x86 - 分段与分页详解
    x86 - 特权级别 CPL / RPL / DPL / IOPL
    x86 - 操作系统:中断、陷阱、异常、故障、终止
    x86 - 描述符详解:存储/系统段描述符、门描述符


      8086 具有 16 位的段寄存器、指令指针寄存器和通用寄存器(CS、SS、DS、ES、IP、AX、BX、CX、DX、SI、DI、BP、SP),因此,我们称它为 16 位的处理器。尽管它可以访问 1MB 的内存,但是只能分段进行,而且由于只能使用 16 位的段内偏移量,故段的长度最大只能是 64KB。8086 只有一种工作模式,即实模式;当然,这个名称是后来才提出来的。

    一、处理器架构

    在这里插入图片描述
      8086 CPU 中寄存器总共为 14 个,且均为 16 位 。即 AX,BX,CX,DX,SP,BP,SI,DI,IP,FLAG,CS,DS,SS,ES 共 14 个。而这 14 个寄存器按照一定方式又分为了通用寄存器,控制寄存器和段寄存器。
    通用寄存器

    缩写含义
    AX,BX,CX,DX
    称作为数据寄存器
    AX (Accumulator):累加寄存器,也称之为累加器;
    BX (Base):基地址寄存器;
    CX (Count):计数器寄存器;
    DX (Data):数据寄存器;
    SP 和 BP
    又称作为指针寄存器
    SP (Stack Pointer):堆栈指针寄存器;
    BP (Base Pointer):基指针寄存器;
    SI 和 DI
    又称作为变址寄存器
    SI (Source Index):源变址寄存器;
    DI (Destination Index):目的变址寄存器;

    控制寄存器
      IP (Instruction Pointer):指令指针寄存器;
      FLAG:标志寄存器;
    段寄存器
      CS (Code Segment):代码段寄存器;
      DS (Data Segment):数据段寄存器;
      SS (Stack Segment):堆栈段寄存器;
      ES (Extra Segment):附加段寄存器;

    二、内存机制

    分段机制

      想象一下,如果我们在程序中完全使用物理地址对数据、代码进行定位,那我们必须保证计算机会按照我们预想的那样,将程序完整的读取到我们指定的内存区域(实际上这是完全不可能的)。因此,为了能够让程序具有通用性,我们需要在编程时使用相对地址或者偏移地址,而不能使用真实的物理地址,因此引入了分段机制。当程序加载时,这些相对地址还要根据程序实际被加载的位置重新计算,从而保证数据能够从正确的位置被读取到。
      其实段也就是在编程时,我们将若干个地址连续的内存单元看做是一个段,然后通过将一个段地址左移 4 位形成基地址(取决于8086独特的编制方式),再通过这个基地址来定位这个段的起始地址,然后,再通过偏移地址便可以精确定位到段中的内存单元了。

      当采用分段策略之后,一个内存单元的地址实际上就可以用“段:偏移”或者 “段地址:偏移地址”来表示,这就是通常所说的逻辑地址。
      为了在硬件一级提供对“段地址:偏移地址”内存访问模式的支持,处理器至少要提供两个段寄存器,分别是代码段(Code Segment,CS)寄存器和数据段(Data Segment,DS)寄存器。对 CS 内容的改变将导致处理器从新的代码段开始执行。同样,在开始访问内存中的数据之前,也必须首先设置好 DS 寄存器,使之指向数据段。 (SS (Stack Segment) 栈段也很重要)
      除此之外,最重要的是,当处理器访问内存时,它把指令中指定的内存地址看成是段内的偏移地址,而不是物理地址。这样,一旦处理器遇到一条访问内存的指令,它将把 DS 中的数据段起始地址和指令中提供的段内偏移相加,来得到访问内存所需要的物理地址。

      注意,由于短地址是由16位寄存器左移4位得来的,因此 8086 处理器的逻辑分段,起始地址都是 16 的倍数,这称为是按 16 字节对齐的。而段偏移也是由16位寄存器得到的,因此段的最大长度为64K。

    内存访问

      8086一共只有20位地址线(所以地址空间只有1MB),以及8个16位的通用寄存器,以及4个16位的段寄存器。所以为了能够通过这些16位的寄存器去构成20位的主存地址,必须采取一种特殊的方式。当某个指令想要访问某个内存地址时,它通常需要用下面的这种格式来表示:

    	(段基址:段偏移量)
    

      第一个字段是段基址,它的值是由段寄存器提供的。段寄存器有4种,%cs,%ds,%ss,%es。具体这个指令采用哪个段寄存器是由这个指令的类型来决定的。比如要取指令就是采用 %cs 寄存器(jmp, call),要读取或写入数据就是 %ds 寄存器(mov),如果要对堆栈操作就是 %ss 寄存器(push, pop)。总之,不管什么指令,都会有一个段寄存器提供一个16位的段基址。
      第二字段是段内偏移量,代表你要访问的这个内存地址距离这个段基址的偏移。它的值就是由通用寄存器来提供的,所以也是16位。

      那么问题来了,两个16位的值如何组合成一个20位的地址呢?8086 采用的方式是把段寄存器所提供的段基址先向左移4位。这样就变成了一个20位的值,然后再与段偏移量相加。所以算法如下:

    	物理地址 = 段基址<<4 + 段内偏移
    

      所以假设 %cs中的值是 0xff00,%ax = 0x0110。则 (%cs:%ax) 这个地址对应的真实物理地址是

    	0xff00<<4 + 0x0110 = 0xff110。
    

      上面就是实模式访问内存地址的原理。

    通用寄存器

    • 8086 处理器内部有 8 个 16 位的通用寄存器,分别被命名为 AX、BX、CX、DX、SI、DI、BP、SP。“通用”的意思是,它们之中的大部分都可以根据需要用于多种目的。
    • 因为这 8 个寄存器都是 16 位的,所以通常用于进行 16位的操作。比如, 可以在这 8 个寄存器之间互相传送数据,它们之间也可以进行算术逻辑运算;也可以在它们和内存单元之间进行 16位的数据传送或者算术逻辑运算。
    • 同时,这 8 个寄存器中的前 4 个,即 AX、BX、CX 和 DX,又各自可以拆分成两个 8位的寄存器来使用,总共可以提供 8 个 8 位的寄存器 AH、AL、BH、BL、CH、CL、DH 和DL。这样一来,当需要在寄存器和寄存器之间,或者寄存器和内存单元之间进行 8 位的数据传送或者算术逻辑运算时,使用它们就很方便。

    在这里插入图片描述
      将一个 16 位的寄存器当成两个 8 位的寄存器来用时,对其中一个 8 位寄存器的操作不会影响到另一个 8 位寄存器。举个例子来说,当你操作寄存器 AL 时,不会影响到 AH 中的内容。

    AX 寄存器

      AX 的另外一个名字叫做累加寄存器或者简称为累加器,可以说是使用率最高的寄存器;除此之外,一些特殊指令都需要使用AX进行存储和运算:

    • 8086 处理器提供了除法指令 div,它可以做两种类型的除法。
      (1) 第一种类型是用 16 位的二进制数除以 8 位的二进制数。在这种情况下,被除数必须在寄存器 AX 中,必须事先传送到 AX 寄存器里。除数可以由 8 位的通用寄存器或者内存单元提供。指令执行后,商在寄存器 AL 中,余数在寄存器 AH 中;
      (2) 第二种类型是用32 位的二进制数除以16 位的二进制数。在这种情况下,因为 16 位的处理器无法直接提供 32 位的被除数,故要求被除数的高 16 位在DX 中,低 16 位在 AX 中,用“DX:AX”来表示 32 位的被除数
    • MUL 指令可以用 8 位的通用寄存器或者内存单元中的数和寄存器 AL 中的内容相乘,结果是 16 位,在 AX 寄存器中;也可以用 16 位的通用寄存器或者内存单元中的数和寄存器 AX 中的内容相乘,结果是 32 位,高 16 位和低 16 位分别在 DX 和 AX 中。

    BX 寄存器

      除了暂存一般性数据的功能外,BX 作为通用寄存器的一种,BX 主要还是用于其专属功能 – 寻址(寻址物理内存地址)上,BX 寄存器中存放的数据一般是用来作为偏移地址使用的。
      在 8086 处理器上,如果要用寄存器来提供偏移地址(以 […] 的方式使用),只能使用 BX、SI、DI、BP,不能使用其他寄存器。 比如:

    	mov [bx],dl  
    

      指令的作用是把 DL 中的内容,传送到以 DS 的内容为段地址,以 BX 的内容为偏移地址的内存单元中去。注意,指令中的中括号是必需的,否则就是传送到 BX 中,而不是 BX 的内容所指示的内存单元了。

    CX 寄存器

      CX 中的 C 被翻译为 Counter 也就是计数器的功能,当在汇编指令中使用循环 LOOP 指令时,可以通过 CX 来指定需要循环的次数;
      loop 指令的功能是重复执行一段相同的代码,处理器在执行它的时候会顺序做两件事:

    • 将寄存器 CX 的内容减一;
    • 如果 CX 的内容不为零,转移到指定的位置处执行,否则顺序执行后面的指令。

    DX 寄存器

      DX 寄存器和 AX一样,都需要用在特殊指令 DIV,MUL中:
      即当在使用 DIV 指令进行除法运算时,如果除数为 16 位时,被除数将会是 32 位,而被除数的高 16 位就是存放在 DX 中,而且执行完 DIV 指令后,本次除法运算所产生的余数将会保存在 DX 中;
      同时,在执行 MUL 指令时,如果两个相乘的数都是 16 位的话,那么相乘后产生的结果显然需要 32 位来保存,而这 32 位的结果的高 16 位就是存放在 DX 寄存器中 。

    指针寄存器 BP

      这里只介绍BP,SP会和SS一起介绍(堆栈);
      BP (Base Pointer)也就是基指针寄存器,它和其他的几个用来进行寻址操作所使用的寄存器(还有 BX,SI,DI)没有太大的区别。
      当以 […] 的方式访问内存单元而且在 […] 中使用了寄存器 BP 的话,如果在指令中没有明确或者说是显示的给出段地址时,段地址则使用默认的 SS 寄存器中的值(BX,SI,DI 会默认使用 DS 段寄存器)
      比如 DS:[BP] 则在这里明确给出了段地址位于 DS 中,这里代表的内存单元即是段地址为 DS ,偏移量为 BP 寄存器中的值的内存单元,而如果单单是使用 [BP] 的话,则代表的内存单元是段地址为 SS,偏移量为 BP 寄存器中的值的内存单元;
      并且 BP 寄存器主要适用于给出堆栈中数据区的偏移,从而可以方便的实现直接存取堆栈中的数据。

    变址寄存器 SI/DI

      变址寄存器和上面介绍的指针寄存器(也就是 BP 和 SP),它们的功能其实都是用于存放某个存储单元地址的偏移,或者是用于某组存储单元开始地址的偏移,即作为存储器指针使用。
      SI (Source Index) 是源变址寄存器,DI (Destination Index) 即是目的变址寄存器,8086 CPU 中的 SI 寄存器和 DI 寄存器其实和 BX 寄存器的功能是差不多的,只是有一些特殊指令必须要用到它们。
      8086 提供了 movsb 和 movsw 指令:

    • 这两个指令通常用于把数据从内存中的一个地方批量地传送(复制)到另一个地方,处理器把它们看成是数据串。movsb 的传送是以字节为单位的,而 movsw 的传送是以字为单位的。
    • movsb 和 movsw 指令执行时,原始数据串的段地址由 DS 指定,偏移地址由 SI 指定,简写为 DS:SI;要传送到的目的地址由 ES:DI 指定;传送的字节数(movsb)或者字数(movsw)由 CX 指定。
    • 标志寄存器 FLAGS 第 10 位是方向标志 DF(Direction Flag),通过将这一位清零或者置 1,就能控制 movsb 和 movsw 的传送方向(正向传送是指传送操作的方向是从内存区域的低地址端到高地址端;反向传送则正好相反)
    • 不管是正向传送还是反向传送,也不管每次传送的是字节还是字,每传送一次,CX 的内容自动减一。
    • 注意:单纯的 movsw 只能执行一次,如果希望处理器自动地反复执行,需要加上指令前缀 rep(repeat),意思是 CX 不为零则重复。rep movsw 的操作码是0xF3 0xA5,它将重复执行 movsw 直到 CX 的内容为零。

    其他寄存器

    CS 寄存器 和 IP 寄存器

      CS:IP 两个寄存器指示了 CPU 当前将要读取的指令的地址,其中 CS 为代码段寄存器,而 IP 为指令指针寄存器 。
      IP 是指令指针(Instruction Pointer)寄存器,它只和 CS 一起使用,而且只有处理器才能直接改变它的内容。当一段代码开始执行时,CS 指向代码段的起始地址,IP 则指向段内偏移。
      这样,由 CS 和 IP 共同形成逻辑地址,并由总线接口部件变换成物理地址来取得指令。然后,处理器会自动根据当前指令的长度来改变 IP 的值,使它指向下一条指令。

    SS 寄存器和 SP 寄存器

      和代码段、数据段和附加段一样,堆栈也被定义成一个内存段,叫堆栈段(Stack Segment),由段寄存器 SS 指向。SS 指向栈顶,SP 存储栈顶的偏移地址,在任何时刻,SS:SP 都是指向栈顶元素
      针对堆栈的操作有两种,分别是将数据推进堆栈(push)和从堆栈中弹出数据(pop)。简单地说,就是压栈和出栈。压栈和出栈只能在一端进行,所以需要用堆栈指针寄存器 SP(Stack Pointer)来指示下一个数据应当压入堆栈内的什么位置,或者数据从哪里出栈。栈的内存结构是从上到下扩展的

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

    DS 寄存器和 ES 寄存器

      顾名思义,DS是数据段(Data Segment)寄存器,ES是附加段(Extra Segment)寄存器。
      通常在使用一些数据操作指令时,默认将DS作为段基址,比如:

    	MOV [BX],AL
    

      当我们定义好段地址后,每一次 CPU 执行到 [BX] 时,便会默认的从 DS 中取值,并且将取得的值作为段地址,因此,当 [BX] 为 0001H 时,CPU 会从 DS 中取得一个 1000H ,由这两个一合成即可以得到正确的物理地址 1000H:0001H 。
      注意:8086 CPU 不支持直接将一个数据送入段寄存器中,一般是先将数据送入通用寄存器,再由通用寄存器送入段寄存器。

    标志寄存器(FLAG)

      标志寄存器设计为16位,实际使用9位:
       其中6位用以存放算术逻辑单元运算后的结果特征,称为状态标志;
       另外3位通过人为设置,用以控制8086的三种特定操作,称为控制标志。
    在这里插入图片描述
      6个状态标志位定义如下:

    位置英文中文作用
    D0CF(Carry FLag)进位标志用于反映运算是否产生进位或借位。如果运算结果的最高位产生一个进位或借位,则CF置1,否则置0。运算结果的最高位包括字操作的第15位和字节操作的第7位。移位指令也会将操作数的最高位或最低位移入CF。
    D2PF(Parity FLag)奇偶标志用于反映运算结果低8位中“1”的个数。“1”的个数为偶数,则PF置1,否则置0。
    D4AF(Auxiliary Carry FLag)辅助进位标志算数操作结果的第三位(从0开始计数)如果产生了进位或者借位则将其置为1,否则置为0,常在BCD(binary-codedecimal)算术运算中被使用。
    D6ZF(Zero FLag)零标志用于判断结果是否为0。运算结果0,ZF置1,否则置0。
    D7SF(Sign FLag)符号标志用于反映运算结果的符号,运算结果为负,SF置1,否则置0。因为有符号数采用补码的形式表示,所以SF与运算结果的最高位相同。
    D11OF(OverFlow FLag)溢出标志反映有符号数加减运算是否溢出。如果运算结果超过了8位或者16位有符号数的表示范围,则OF置1,否则置0。

      3个控制标志位定义如下:

    位置英文中文作用
    D8TF(Trap FLag)跟踪/陷阱/单步标志当TF被设置为1时,CPU进入单步模式,所谓单步模式就是CPU在每执行一步指令后都产生一个单步中断。主要用于程序的调试。8086/8088中没有专门用来置位和清零TF的命令,需要用其他办法。
    D9IF(Interrupt-Enable FLag)中断标志决定CPU是否响应外部可屏蔽中断请求。IF为1时,CPU允许响应外部的可屏蔽中断请求。
    D11DF(Direction FLag)方向标志决定串操作指令执行时有关指针寄存器调整方向。当DF为1时,串操作指令按递减方式改变有关存储器指针值,每次操作后使SI、DI递减。

    三、参考资料

      《x86汇编语言 从实模式到保护模式》
      https://blog.csdn.net/weixin_40913261/article/details/90762210
      https://blog.csdn.net/weixin_42109012/article/details/100148721
      https://blog.csdn.net/sky1679/article/details/89785382
      https://blog.csdn.net/song_lee/article/details/105297902
      https://www.cnblogs.com/wanghetao/archive/2011/10/28/2228130.html
      https://zhuanlan.zhihu.com/p/272135463
      https://www.cnblogs.com/nullecho/p/10266467.html
      https://www.cnblogs.com/kukudi/p/11416993.html

    展开全文
  • 51单片机之TMOD寄存器

    千次阅读 2020-07-14 11:38:46
    51单片机之TMOD寄存器TMOD格式图GATE(门控位)C/T( 定时/计数模式选择位)M1M0(工作方式设置位) TMOD格式图 TMOD(定时器/计数器工作方式寄存器)低4位用于T0,高4位用于T1 GATE(门控位) 用于控制定时器启动...

    TMOD格式图

    TMOD(定时器/计数器工作方式寄存器)低4位用于T0,高4位用于T1
    格式图

    GATE(门控位)

    用于控制定时器启动是否受外部中断源的影响 
          当GATE=0时,只要用软件使TR0或TR1等于1,就可以启动T0或T1定时/计数器工作。
          当GATE=1时,除了用软件使TR0或TR1等于1外,还要使外部中断引脚INT0/1为高电平,这样定时/计数器才能启动工作。
          注意:GATE=0表示控制定时器启动不受外部中断源的影响
    

    C/T( 定时/计数模式选择位)

     C/T=0为定时模式,C/T=1为计数模式。
    

    M1M0(工作方式设置位)

    定时/计数器工作方式设置表

    展开全文
  • 移位寄存器

    2020-12-09 01:57:52
    移位寄存器是暂时存放数据的部件,同时它还具有移位...通常可按数据传输方式的不同对CMOS移位寄存器进行分类。移位寄存器的数据输入方式有串行输入和并行输入之分。串行输入就是在时钟脉冲作用下,把要输入的数据从一个
  • 第二章-寄存器(CPU工作原理)CPU概述寄存器概述 CPU概述 一个典型的CPU由运算器、控制器、寄存器等器件组成,这些器件靠内部总线相连。 区别: 1.内部总线实现CPU内部各个器件之间的联系。 2.外部总线实现CPU和主板...

    CPU概述

    一个典型的CPU由运算器控制器寄存器等器件组成,这些器件靠内部总线相连。

    区别:
    1.内部总线实现CPU内部各个器件之间的联系。
    2.外部总线实现CPU和主板上其它器件的联系。

    寄存器概述

    • 8986CPU有14个寄存器,它们的名称为:AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW。

    2.1通用寄存器

    • 8986CPU的所有寄存器都是16位的,可以存放两个字节。
    • AX、BX、CX、DX通常用来存放一般性数据,被称为通用寄存器。

    16位寄存器逻辑结构:
    在这里插入图片描述

    16位数据在寄存器中的存放情况:
    在这里插入图片描述

    8086上一代CPU中的寄存器是8位的,为了保证兼容性,四个寄存器都可以分为两个独立的8位寄存器使用。

    在这里插入图片描述
    只用AL,AH为零。就可以兼容了。

    在这里插入图片描述

    2.2字(word)在寄存器中的存储

    • 一个字可以存在一个16位寄存器。
    • 1word=2Byte
    • 在这里插入图片描述

    2.3几条汇编指令

    在这里插入图片描述
    汇编不区分大小写!

    2.4物理地址

    • CPU访问内存单元时要给出内存单元的地址。所有的内存单元构成的存储空间是一个一维的线性空间。
    • 我们将这个唯一的地址称为物理地址。

    2.5 16位结构的CPU

    概况的讲,16位结构描述了一个CPU的特征:

    1. 运算器一次最多可以处理16位的数据。
    2. 寄存器的最大宽度为16位。
    3. 寄存器和运算器之间的通路是16位的。

    2.6 8086CPU给出物理地址的方法

    • 8086有20位地址总线,可传送20位地址,寻址能力为1M。
    • 8086内部为16位结构,它只能传送16位的地址,表现出的寻址能力却只有64K。
    • 8086CPU采用一种在内部用两个16位地址合成的方法来形成一个20位的物理地址。

    在这里插入图片描述

    物理地址=段地址×16+偏移地址
    在这里插入图片描述

    • "段地址×16"更为常用的说法是数据左移4位(二进制位)
    • 在这里插入图片描述

    2.7 “物理地址=段地址×16+偏移地址”本质含义

    在这里插入图片描述
    在这里插入图片描述

    2.8段的概念

    • 错误认识:内存分段
    • 其实:内存并没有分段,段的划分来自于CPU
      在这里插入图片描述
      我们认为有多少个段都可以~

    两个注意点:

    1. 段地址×16必然是16的倍数,所以一个段的起始地址也一定是16的倍数;
    2. 偏移地址为16位,16位地址的寻址能力为64K,所以一个段的长度最大为64K。

    小结

    • CPU访问内存单元时,必须向内存提供内存的物理地址
    • 8086CPU在内部用段地址和偏移地址移位相加的方法形成最终的物理地址

    1.观察下面的地址,读者有什么发现?
    在这里插入图片描述
    结论:CPU可以用不同的段地址和偏移地址形成同一个物理地址。

    2.如果给定一个段地址,仅仅通过变化偏移地址来进行寻址,最多可以定位多少内存单元?

    偏移地址范围:0~FFFFH,64K。

    “数据在21F60H内存单元中。”对于8086PC机的两种描述:

    1. 数据存在内存2000:1F60单元中;
    2. 数据存在内存的2000段中的1F60H单元中。

    可以根据需要,将地址连续、起始地址为16的倍数的一组内存单元定义为一个段。

    2.9段寄存器

    • 段寄存器提供段地址:8986CPU有四个:CS、DS、SS、ES
    • 当8986CPU要访问内存时,由这4个段寄存器提供内存单元的段地址。

    2.10 CS和IP

    1. CS和IP是8086CPU中最关键的寄存器,它们指示了CPU当前要读取指令的地址。
    2. IP是指令指针寄存器。
      在这里插入图片描述

    8086PC工作的简要概述

    1. 从CS:IP指向内存单元读取指令,读取的指令进入指令缓冲器;
    2. IP=IP+所读指令长度,从而指向下一条指令;
    3. 执行指令。转到步骤1,重复过程。

    2.11修改CS、IP的指令

    • 在CPU中,,程序员能够用指令读写的部件只有寄存器,通过改变寄存器中的值控制CPU
    • 同时修改CS、IP的内容:jmp 段地址:偏移地址
    • jmp 2AE3:3
    • jmp 3:0B16
    • 功能:用指令中给出的段地址修改CS,偏移地址修改IP。

    仅仅修改IP的内容:

    • jmp 某一合法寄存器
    • jmp ax(类似于mov IP,ax)

    如何修改AX中的值?

    • mov 指令
      如:mov ax,123

    2.12 代码段

    • 对于8086PC机,在编程时,可以根据需要,将一组内存单元定义为一个段。
    • 可以将长度为N(N<=64kb)的一组代码,存在一组地址连续、起始地址为16的倍数的内存单元中,这段内存是用来存放代码的,从而定义了一个代码段。
    • 在这里插入图片描述
    • CPU只认被CS:IP指向的内存单元中的内容为指令。
    • 所以要将CS:IP指向所定义代码段的第一条指令的首地址。

    2.9~2.12小结

    1. 段地址在8086CPU的寄存器中存放。当8086CPU要访问内存时,由寄存器提供内存单元的段地址。8086CPU有4个段寄存器,其中CS用来存放指令的段地址。
    2. CS存放指令的段地址,IP存放指令的偏移地址。8086机中,任何时刻,CPU将CS:IP指向的内容当作指令执行。
    3. 8086CPU的工作过程:(1)从CS:IP指向内存单元读取指令,读取的指令进入指令缓冲器;(2)IP指向下一条指令;(3)执行指令。(转到步骤(1),重复这个过程。)
    4. 8086CPU提供转移指令修改CS、IP的内容。
    展开全文
  • C51串口的SCON寄存器工作方式

    千次阅读 2020-03-14 13:43:22
    它用于定义串行口的工作方式及实施接收和发送控制。字节地址为98H,其各位定义如下表: 其中fosc为晶振频率 SM2:多机通讯控制位。在方式0时,SM2一定要等于0。在方式1中,当(SM2)=1则只有接收到有效停止位时,RI...
  • 寄存器工作原理寄存器的功能十分重要,CPU对存储器中的数据进行处理时,往往先把数据取到内部寄存器中,而后再作处理。外部寄存器是计算机中其它一些部件上用于暂存数据的寄存器,它与CPU之间通过“端口”交换数据,...
  •  在数字电路中,移位寄存器(英语:shift register)是一种在若干相同时间脉冲下工作的触发器为基础的器件,数据以并行或串行的方式输入到该器件中,然后每个时间脉冲依次向左或右移动一个比特,在输出端进行输出。...
  • 一、什么是寄存器   STM32编程通常有两种编程方法,一种是寄存器编程;另一种是固件库编程,其中寄存器编程是基础,而固件库编程是在寄存器编程的基础上升级而来的一种易于学习和开发的方法,是学习STM32编程时需...
  • MCS-51单片机含有2个定时器/计数器,具有4种工作方式。具有两种工作模式(计数器模式和定时器模式)  MCS-51单片机含有1个全双工串行口,具有4种工作方式。  TMOD-》定时器/计数器方式控制寄存器  TCON-》...
  • C51单片机串口工作的四种方式总结

    万次阅读 多人点赞 2020-06-23 16:25:28
    方式0:同步移位寄存器输入输出方式 1. 利用移位寄存器实现串行/并行的转换(功能) 2. 波特率:fosc/12 3. RXD(P3.0)----用于串行数据的输入和输出 TXD(P3.1)----充当输出的移位时钟 4. 数据大小:8位 5. 方式...
  • 寄存器位于中央处理器(CPU)的芯片(Chip)中,暂时而快速存取的记忆存储空间,帮助CPU执行算术、逻辑或转移运算,只存储处理过程中的资料或是指令,之后再...用这些控制命令可对接口电路的工作方式和功能进行控制,这
  • 工作中收获的关于HMC765芯片输出不同VCO频率的相关寄存器的配置,内有实际测试记录
  • AT系列单片机的硬件体系结构结构引脚存储器配置专用寄存器时钟与时序工作方式已标PPT课件.pptx
  • 文章目录寄存器(CPU工作原理)通用寄存器几条汇编指令 寄存器(CPU工作原理) CPU = 运算器 + 控制器 +【寄存器】,器件之间通过总线相连; 8086CPU 有14个寄存器,名称分别为: AX,BX,CX,DX,SI,DI,SP,BP,...
  • GPIO的8种工作方式一、GPIO基本结构和工作方式1、战舰/精英板2、Min板3、基本结构4、工作方式二、GPIO寄存器说明1、GPIO相关寄存器2、端口配置低寄存器(GPIOx_CRL)、端口配置高寄存器(GPIOx_CRH)3、端口输入数据...
  • 寄存器电路

    2021-07-28 06:44:41
    在数字电路系统工作过程中,把正在处理的二进制数据或代码暂时存储起来的操作叫做寄存,寄存器电路就是实现寄存功能的电路,是数字逻辑电路的基础模块。[1]中文名寄存器电路外文名register circuit拼音jì cún qì ...
  • 寄存器,寄存器是什么意思

    千次阅读 2021-07-28 06:43:33
    寄存器,寄存器是什么意思寄存器定义寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和位址。在中央处理器的控制部件中,包含的寄存器有指令寄存器(IR)和程序计数器...
  • STM32F103寄存器方式点亮LED流水灯

    千次阅读 2021-10-24 15:35:48
    一、关于STM32芯片寄存器1.什么是寄存器 提到单片机,就不得不提到寄存器。根据百度百科介绍,寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和地址。 简单来说,...
  • 汇编学习之-寄存器(CPU工作原理)

    千次阅读 2022-03-17 12:01:02
    2.1 通用寄存器 2.2 字在寄存器中的存储 关于数制的讨论 2.3 几条汇编指令 2.4 物理地址 2.5 16位结构的CPU 2.6 8086CPU给出物理地址的方法 地址加法器工作原理 2.7 “段地址×16+偏移地址 =物理地址”的本质含义 ...
  • 一、GPIO工作方式 1.输入浮空模式:CPU可以读取到外部的高低电平,输入的高低是不确定的完全由外部输入决定。例如按键可以使用这个模式。 2.输入上拉模式:就是在无信号状态默认是高电平,当我们输入的低电平是...
  • GPIO工作原理:寄存器描述和配置方法
  • 通用寄存器

    2021-07-28 06:43:31
    通用寄存器可用于传送和暂存数据,也可参与算术逻辑运算,并保存运算结果。除此之外,它们还各自具有一些特殊功能。汇编语言程序员必须熟悉每个寄存器的一般用途和特殊用途,只有这样,才能在程序中做到正确、合理地...
  • ARM的工作模式以及寄存器组织总结
  • 51单片机寄存器间接寻址方式与举例

    千次阅读 2021-05-22 06:24:31
    寄存间接寻址方式是指寄存器中存放的是操作数的地址,即操作数是通过寄存器间接得到的,因此称为寄存器间接寻址。MCS-51单片机规定工作寄存器的R0、R1做为间接寻址寄存器。用于寻址内部或外部数据存储器的256个单元...
  • 文章目录指令格式指令中的(目标 / 源)操作数来源一、立即数寻址二、寄存器寻址三、存储器寻址3.1 直接寻址3.2 寄存器间接寻址3.3 基址寻址3.4 变址寻址3.5 基址变址寻址3.6 带位移的基址加变址寻址方式3.7 小结---...
  • 寄存器的基本原理

    千次阅读 2020-01-22 09:56:41
    CPU中有很多的寄存器,有临时保存数据的通用寄存器,也有专门保存指令编码或者指令地址的寄存器。它们都有存储信息的能力。 那在这一节,我们就来分析这些寄存器是如何实现的。 在CPU当中用来存放信息的非常重要的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 184,556
精华内容 73,822
热门标签
关键字:

寄存器的工作方式