精华内容
下载资源
问答
  • 那它 8 16 寄存器又有什么关系呢? 从网上找到一个简洁明了的图片: EAX 是 32 的, 也就是 4 个字节大小; 它的低两就是 AX; AX 是 16 的, 又分 2 个字节; 它的高字节是 AH、低字节是 AL; ...
    王爽老师书上说, CPU 内部主要就是寄存器.
    现在我们在 32 位的系统下工作, 当然主要使用的是 32 位寄存器; 那它和 8 位、16 位的寄存器又有什么关系呢?
    从网上找到一个简洁明了的图片:

    r_hb.gif


    EAX 是 32 位的, 也就是 4 个字节大小; 它的低两位就是 AX;
    AX 是 16 位的, 又分 2 个字节; 它的高字节是 AH、低字节是 AL;
    AH 与 AL 是 8 位的.
    这样就兼容了以前的 16 位与 8 位.

    同理,
    EBX 就包含着 BX BH BL;
    ECX 就包含着 CX CH CL;
    EDX 就包含着 DX DH DL;

    好啊, 一下子认识了那么多寄存器!


    按照这个道理, 如果给 EAX 赋了值, 那么 AX AH AL 也就都有了值;
    如果给 AL 赋了值, 那么 AX EAX 也就有了值.
    //测试1
    var
      i: integer;  {4 字节、32 位}
      w: word;     {2 字节、16 位}
      b1,b2: byte; {1 字节、 4 位}
    begin
      i  := maxint;
      w  := 0;
      b1 := 0;
      b2 := 0;
    
      asm
        mov ecx, i
        mov w, cx
        mov b1, ch
        mov b2, cl
      end;
    
      ShowMessage(Format('w=%d; b1=%d; b2=%d',[w,b1,b2]));
    
    {结果显示: w=65535; b1=255; b2=255
    
      果然没错, 给 ecx 赋值后, cx ch cl 都有值了!
    }
    end;
    
    
    //测试2
    var
      i: integer;  {4 字节、32 位}
      w: word;     {2 字节、16 位}
      b: byte;     {1 字节、 4 位}
    begin
      b := 255;
      i := 0;
      w := 0;
    
      asm
        mov cl, b
        mov w, cx
        mov i, ecx
      end;
    
      ShowMessage(Format('i=%d; w=%d',[i,w]));
    
    {结果显示: i=255; w=255
    
      这好像是没有问题的, 我用 al ax eax 三个寄存器测试也是如此;
      
    }
    end;
    
    展开全文
  • 刚开始学习STM8单片机时,看别人的代码,在设置寄存器的时候经常使用,或、与、左移、右移等运算,就很不理解,为什么不直接给寄存器赋值,非要搞的这么复杂。直到后来程序写的多了,才明白这样写的好处。比如...

    刚开始学习STM8单片机时,看别人的代码,在设置寄存器的时候经常使用,位或、位与、左移、右移等运算,就很不理解,为什么不直接给寄存器赋值,非要搞的这么复杂。直到后来程序写的多了,才明白这样写的好处。比如我们现在要设置PB5口为输出口。首先我们需要设置PB口的方向寄存器PB_DDR。
    在这里插入图片描述
    我们要设置PB5口为输出,那么就要把DDR5位设置为1。那么要设置的寄存器PB_DDR寄存器二进制数据为 0010 0000,转换为16进制为 0x20。设置寄存器的语句为

    PB_DDR = 0x20;
    

    这样操作寄存器看起来没什么问题,也挺方便。唯一的问题就是每次要先将设置的二进制数确定好,然后再转换为16进制数,再赋值给寄存器。代码少的时候没什么感觉,但是一旦代码量比较大,要设置的寄存器比较多时,再这样操作就比较麻烦,特别是设置的寄存器值要进行改变时再去计算二进制数,在转换成16进制数,就非常麻烦。而且还要不停的查阅参考手册,来确认寄存器的每一位值。一不小心很容易设置错,排除原因的时候又很难发现。
    为了方便程序的编写和维护,这时候就需要用到移位运算。还是上面的例子,要设置PB5口为输出,需要将PB_DDR寄存器的第5位设置为1,其他位不变。那么将1左移5位,第五位不就刚好是1了吗。我们来看看移位操作,首先1的二进制数为
    0000 0001
    将这个数左移五位,最高位移出去,最低位补0,那么,向左移动5位后,变为
    0010 0000
    转换为16进制数为 0x20。于是对PB_DDR寄存器的设置语句可以改为:

     PB_DDR = 1<<5;
    

    将1左移5位,然后赋值给PB_DDR寄存器。这样从代码上一眼就能看出来这是设置PB_DDR寄存器的DDR5为1。比上面的那种操作方式看起来简洁明了。
    如果要继续设置PB4为输出的时候,寄存器的设置就可以写为:

    		PB_DDR = 1<<4;
    

    这样就将PB4口设置为了输出口。这时我们发现了一个问题,当将PB4设置为输出口时寄存器的值变为 0001 0000,DDR4为0,但是又将上一步设置的DDR5的值由1 变为0了,将PB4设置为输出后,又将PB5设置为了输入,改变了设计初衷。
    那么如何解决这种问题呢,就需要用到位运算。先看看位或运算和位与运算的区别:
    位或运算 |: 位之间进行或运算,如果有一个位为1,结果就为1。
    位与运算&:位之间进行与运算,如果有一个位为0,结果就为0。
    在设置PB4的时候不希望影响到PB5位,那么就可以用位或运算,给第4位或1,不管第4位以前的值是1还是0,与1进行或运算后,第4位的值就会变成1。那么在给PB_DDR赋值时,先进行或运算.

    		PB_DDR = PB_DDR | 0x10;
    

    同样为了方便程序书写和阅读,将16进制数改为位移运算。

    	 	PB_DDR = PB_DDR | (1<<4);
    

    为了书写简便,可以将上面的语句简写为:

    		PB_DDR |= 1<<4;
    

    这样在操作寄存器其中一位的时候,不会影响到其他位。这时如果设置PB4、PB5为输出,可以这样写:

    		PB_DDR |= 1<<4;
      		PB_DDR |= 1<<5;
    

    这样通过位移运算和位或运算的组合,可以很方便的设置寄存器值。 从语句上就能很清楚的看到是设置 PB_DDR寄存器的第4位和第5位为1。
    如果这时候又需要将PB4口设置为输入模式,那么就需要将DDR4位由1变为0。位或运算只能将0变为1,不能将1变为0。而位与运算可以将1变为0,那么可以用位与运算实现。给PB_DDR寄存器的第4位位与0,就能将DDR4位由1变为0。
    第4位为0,其他位为1二进制数为 1110 1111 转换为16进制数为0xEF。

          PB_DDR = PB_DDR & 0xEF;
    

    这样在不影响其他位的情况下,将第4位变为了0。但是这样换算16进制也很麻烦,能不能同样用位移运算实现。但是位移运算是高位溢出后,低位自动补0。我们需要的是自动补1,那么有没有其他办法实现。我们观察设置第4位为0和第4位为1时的二进制数据
    0001 0000
    1110 1111
    这两组数据刚好互补,那么将第4位为1其他位为0的数进行取反操作,那么得到的数刚好就是我们位与运算需要的数。
    那么上面的设置语句可以改为

           PB_DDR = PB_DDR &( ~(1<<4));
    

    将1左移4位后,先取反,让第4位变为0,其他位变为1,在和寄存器原先的值进行位与运算,那么就可以在不影响其他位的情况下,将第4位由1变为0。
    上面的设置语句可以简写为:

    	    PB_DDR &=   ~(1<<4);
    

    通过增加一个取反运算,就可以实现用位移运算对寄存器某一位清0。
    通过上面的分析可以得出一个结论 位或 | 运算可以实现将寄存器的某一位置1,而 位与& 运算可以实现将寄存器的某一位清0。通过这几种运算符的组合,设置寄存器时就会很方便快捷。
    如要将PB4设置为输出,PB5设置为输入,那么运用上面的方法,可以很轻松的写出

     		PB_DDR |= 1<<4;
      		PB_DDR &= ~(1<<5);
    

    这时候在看用以前对寄存器的操作方法,先设置对应的二进制数为 DDR4 为1 DDR5为0 0001 0000 转换为16进制数位 0x10 设置语句为

    	    PB_DDR = 0x10;
    

    明显可以发现直接设置寄存器操作起来麻烦,程序可读性很差。要修改寄存器的值时很费劲。
    所以在以后代码编写中,推荐大家多用位或、位与、左移、右移、取反这些运算的组合方式进行寄存器设置。

    展开全文
  • 有关I2C总线时序,下面的文章写得很好,推荐阅读 ... 8位设备地址,8位寄存器地址,8位数据的情况完全够了 下面我想补充的是8位设备地址,16位寄存器地址,16位数据的传输时序,如下: ...

    有关I2C总线时序,下面的文章写得很好,推荐阅读

    https://www.cnblogs.com/BitArt/archive/2013/05/28/3103917.html#commentform

    8位设备地址,8位寄存器地址,8位数据的情况完全够了

    下面我想补充的是8位设备地址,16位寄存器地址,16位数据的传输时序,如下:

     

    展开全文
  • 三课_8位和16位通用寄存器

    千次阅读 2020-10-24 17:44:15
    前言 很久没写东西了,今晚下班抽空写写。 这部分的内容很简单,但是对...对比32位和16寄存器的名称,会发现其实16位的寄存器只是少的一个字母E。 今天讲的8位的寄存器分别为:AL、CL、DL、BL、AH、CH、DH、BH。

    前言

    很久没写东西了,今晚下班抽空写写。

    这部分的内容很简单,但是对刚接触的同学来说可能比较难理解。今天讲8位的和16位的通用寄存器。

    在十一课中,我们知道了32位的通用寄存器。分别是EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI

    今天讲的16位寄存器分别为:AX、CX、DX、BX、SP、BP、SI、DI

    对比32位和16位寄存器的名称,会发现其实16位的寄存器只是少的一个字母E

    今天讲的8位的寄存器分别为:AL、CL、DL、BL、AH、CH、DH、BH

    下面的内容可能对刚入门的同学比较难理解一点。

    首先说明一点,这些8位、16位、32位的寄存器,并不是相互独立的8位寄存器在16位寄存器中,而16位寄存器在32位寄存器中。或者说:32位寄存器中,取015位的部分组成16位寄存器,16位寄存器对半分,成为8位寄存器。不明白的看下图。

    可能还有同学不明白,下面以EAX为例讲讲它们的关系。看下图,32位寄存器EAX,占用031位。把EAX从中间分开,取015,就是16位寄存器AX。再从AX中间分开,低位07位为8位寄存器AL;高位815位为8位寄存器AH

    在OD中测试寄存器之间的关系

    用OD随便打开一个exe。(OD的使用请看上节课),往EAX中写满A。输入:mov eax,0xAAAAAAAA

    往16位寄存器AX中写满B,输入:mov ax,0xBBBB

    往8位寄存器AL中写满C,输入:mov al,0xCC

    往8位寄存器AH中写满D,输入:mov ah,0xDD

    写完上面的内容开始测试运行结果,按F8。可以看到32位寄存器EAX写满A

    再按F8单步运行,可以看到16位寄存器AX写满B,(即EAX中的低16位)。

    再按F8,可以看到8位寄存器AL写满C,(即EAX中的07位)。

    再按F8,可以看到8位寄存器AH写满D,(即EAX中的815位)。

    通过上面的讲解应该是了解了。​ 

    写于2020.4.21 22:59

     

    展开全文
  • 汇编 标志寄存器和标志

    千次阅读 2016-11-24 21:42:57
    8086CPU的标志寄存器16位,其中存储的信息通常被称为程序状态字(PSW)。falg寄存器结构
  • 64位和32位的寄存器和汇编的比较

    万次阅读 多人点赞 2016-04-29 00:49:12
    6416寄存器,32只有8个。但是328个都有不同的命名,分别是e _ ,而648个使用了r代替e,也就是r _。e开头的寄存器命名依然可以直接运用于相应寄存器的低32。而剩下的寄存器名则是从r8 - r15,其...
  • 32位16位8位寄存器及编号

    千次阅读 2014-10-06 11:28:27
    记住寄存器的编码对以后硬编码有用……
  • verilog8位寄存器

    2018-04-20 13:05:50
    verilog初学者设计8位寄存器,提供verilog源代码,里面不含仿真文件。
  • 寄存器小精灵(Register Sprite)是基于python tkinter编写的,具有良好的界面和一些简单的功能,它可以轻松实现10位、16位、8位和2位之间的转换,方便用于学习各种嵌入式寄存器的位配置,嵌入式工程师的必备神器。
  • 单片机寄存器操作

    千次阅读 2019-03-09 21:16:01
    假如需要将B16的D8~D10改为0001,但是更改D8~D10时又不能改变其它状态:所以需要先将D8~D10 清0,再改为0001 PORTB-&gt;PCR[16] &amp;= 0XFFFFF8FF; //需要修改D8~D10,确保D8~D10为0,其他...
  • 寄存器

    2020-01-18 12:12:58
    寄存器寄存器 CS 代码段 DS 数据段 SS 堆栈段 ES 附加段 ...AH 8位寄存器位于AX的高16位 AL 8位寄存器位于AX的低16位 BX EBX BH BL CX ECX CH CL DX EDX DH DL BP EBP SI ESI D...
  • 寄存器位设置

    千次阅读 2018-09-15 21:17:48
    作为嵌入式工程师,一定要掌握寄存器的控制,想要了解基本的寄存器控制,最简单的方法就是使用单片机练手...假设存在两个8位寄存器GPIOCON1GPIOCON2,分别需要对寄存器1的第7位置0,对寄存器2的第7位置1。 操作如...
  • 16位汇编相关寄存器

    2019-09-17 14:29:23
    文章目录1 X86 16位汇编所涉及的寄存器 1 X86 16位汇编所涉及的寄存器 总共也没几个寄存器啊,为啥就是记不住呢。 8个通用寄存器: 4个段寄存器: 2个控制寄存器: ...
  • 访问 16 位寄存器

    2010-07-19 10:34:00
     OCRnA/B/C 与 ICRn 是 AVR CPU 通过 8 数据总线可以访问的 16 位寄存器。 读 TCNTn、写 16 位寄存器需要两次操作。每个 16 计时器都有一个 8 临时寄存器用来存放其高 8 数据。每个 16 ...
  • 16位寄存器实现32二进制数左移4、 源代码 MOV CL, 04 SHL DX, CL MOV BL, AH SHL AX, CL SHR BL, CL OR DL, BL 说明: MOVCL,04 SHL DX,CL;以上两行指令是把dx左移4,这样dx的最低4为0 MOVBL,AH;...
  • 寄存器结构体和位操作访问方法

    千次阅读 2018-04-02 15:57:54
    1.2.1 传统#define 方法 1.2 外设位域结构体方法综述DSP281x 头文件外设示例使用位域结构体方法,映射访问基于F28x 外设寄存器。本节将介绍这种方法,并把它传统的#define 方法加以比较。1.2.1 传统#define ...
  • 14个16位寄存器 : 通用寄存器 ; 指令指针寄存器 ; 标志寄存器; 段寄存器 通用寄存器(8个): 可以随意修改 数据寄存器(4个) : (通用的) AX(accumulator) : 累加寄存器 ,常用于运算 BX(base) : 基址寄存器 ,常...
  • 32位寄存器

    千次阅读 2015-08-04 19:04:08
    32位寄存器    EBPESP是32的SP,BP  ESP是堆栈指针  EBP是基址指针  ESP与SP的关系就像AX与AL,AH的关系 32CPU所含有的寄存器有: 4个数据寄存器(EAX、EBX、ECXEDX) 2个变址指针...
  • 寄存器位操作总结

    2021-04-19 09:37:59
    1.第八位设置为1,其他位置不变 REG |= (1<<8); 2.第八位设置为0,其他位置不变 REG &=~(1<<8); GPIOA-> BSRRL &=0XFF0F; //将第 4-7 位清 0 GPIOA-> BSRRL |=0X0040; //设置相应位的值...
  • B001-Atmega16-16位寄存器的读写步骤

    千次阅读 2016-06-25 14:05:15
    Atmega16-16位寄存器的读写步骤
  • 实例七— 8位移位寄存器的设计

    万次阅读 2019-02-19 11:12:12
    要求掌握8位移位寄存器原理,并根据原理设计8位移位寄存器模块以及设计相关testbench,最后在Robei可视化仿真软件进行功能实现仿真验证。 设计准备 有一个8比特的数据(初值设为10011100)一个移位设置数据s,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 183,125
精华内容 73,250
关键字:

寄存器16位和8位