寻址方式

1. 立即寻址

  1. 寻址空间:程序存储器。指令的操作数直接存储在程序存储器中,根据指令的不同,操作数可以为8位或者16位。
  2. 指令形式:操作码+立即数/操作码+立即数(高)+立即数(低)
MOV   A,#30H
HMOV   DPTR,#8000H ;80H放入DPH,00H放入DPL

解释:#是用来帮助汇编器区分立即数还是地址的标识

2. 直接寻址

  1. 寻址空间:内部RAM的低128字节(包含4个工作寄存器区,位寻址区和数据缓冲区)、特殊功能寄存器SFR(直接寻址也是访问SFR的唯一方式)
  2. 指令的三种形式
    • 操作码+操作数地址
    • 操作码+操作数地址+立即数
    • 操作码+源操作数地址+目的操作数地址
MOV    A,30H     ;A<-(30)
ANL    30H,#30H ;对(30H)和30H做按位逻辑与

3. 寄存器寻址

  1. 寻址空间:工作寄存器区(为了节省空间,8051设计者实际上没有采用物理意义上的寄存器组,而是将其功能映射到了RAM低32字节),A,B(用于乘除法),CY(位)(carry flag进位标志位),DPTR
  2. 指令形式:(看上去只有操作码,十分紧凑。因为操作的内容,也就是寄存器,已经包含在操作码中,因此这类指令只需要一个字节存储,因此有时候也被成为隐含寻址)。
    • 操作码
    • 操作码+立即数
    • 操作码+直接地址

4. 寄存器间接寻址

  1. 寻址空间:
    • 内部RAM(@R0,@R1,SP)
    • 外部数据存储器(@R0,@R1,@DPTR) 指令所选的寄存器中的内容是实际操作数的地址,这种寻址方式可以实现动态访问和循环处理。
  2. 指令有三种形式:
    • 操作码
    • 操作码+立即数
    • 操作码+直接地址

5. 基址寄存器加变址寄存器间接寻址

  1. 寻址空间:程序存储器
  2. 指令形式:操作码
MOVC A,@A+DPTR
MOVC A,@A+PC

@A+PC的好处在于它具有地址无关性,改变相对位置并不会导致程序运行错误。

6. 相对寻址

  1. 寻址空间:程序存储器
  2. 指令形式:操作码+rel
  3. 该指令主要是用于程序跳转

7. 位寻址

  1. 寻址空间:片内RAM的20H-2FH(位寻址区),SFR中12个能被8整除的字节地址
  2. 这种寻址方法在布尔处理类指令中介绍

这是一份为你精心整理的 Notion 风格笔记。你可以直接复制下面的内容到你的 Notion 页面中,它会自动识别标题、表格和代码块格式。


8051 指令集优化:单字节 MOV 指令详解

核心逻辑: 在 8051 中,凡是**只涉及 A 寄存器与工作寄存器(R0-R7 或 @Ri)**的搬运,都是 1 字节 机器码。这种设计极大地节省了代码空间并提升了取指速度。


📂 第一部分:单字节指令俱乐部 (1-Byte Club)

1. 搬运到累加器 A (MOV A, …)

这些指令将数据从寄存器送入 A。

指令格式二进制格式 (Binary)十六进制范围 (Hex)典型例子
MOV A, Rn1110 1nnnE8H ~ EFHMOV A, R3 → EBH
MOV A, @Ri1110 011iE6H (R0) / E7H (R1)MOV A, @R0 → E6H

2. 从累加器 A 搬出 (MOV Rn/@Ri, A)

这些指令将 A 的结果存回寄存器。

指令格式二进制格式 (Binary)十六进制范围 (Hex)典型例子
MOV Rn, A1111 1nnnF8H ~ FFHMOV R5, A → FDH
MOV @Ri, A1111 011iF6H (R0) / F7H (R1)MOV @R1, A → F7H

3. 外部数据搬运 (MOVX)

专门用于访问外部 RAM,同样是精简的单字节设计。

  • 读取:

    • MOVX A, @Ri (i=0,1) → E2H / E3H

    • MOVX A, @DPTR → E0H

  • 写入:

    • MOVX @Ri, A (i=0,1) → F2H / F3H

    • MOVX @DPTR, A → F0H


🔍 第二部分:为什么它们能做成 1 字节?

秘密武器:嵌入式编码 (Embedded Encoding)

8051 硬件设计者把寄存器的“名字”(编号)直接藏在了操作码的“尾巴”里:

  • 以 MOV A, Rn 为例:
    其二进制是 1110 1[nnn]。

    • 前 5 位 1110 1:告诉 CPU “动作是 MOV,目标是 A”。

    • 后 3 位 [nnn]:告诉 CPU “源是哪个 R”。

    • 因为

            `23=82^3 = 823=8`
          
      

      ,刚好够装下 R0-R7。


⚠️ 第三部分:对比——为什么有些指令需要多字节?

当指令无法将所有信息挤进 8 位时,就需要额外的字节来存放“地址”或“常数”。

指令长度原因解析
MOV A, #data2 字节1 字节存动作,1 字节存 #data (立即数) 本身。
MOV A, direct2 字节1 字节存动作,1 字节存 直接地址 (如 P1 口的 90H)。
MOV DPTR, #data163 字节1 字节存动作,2 字节 存 16 位地址数据。

💡 老师的专家建议 (Pro Tips)

1. 寄存器优先原则

在编写高性能或空间受限的代码时,应拼命将高频使用的变量塞进 R0-R7

  • 收益: 比起使用直接寻址(如 MOV A, 30H),使用 MOV A, R1 能节省 50% 的 Flash 空间 (1 字节 vs 2 字节)。

2. 寻址效率

单字节指令不仅体积小,由于 CPU 无需进行第二次或第三次取指动作(Fetch),其执行效率抗干扰能力在理论上更优。


📅 复习提醒: 下次在 Proteus 调试时,留意单字节指令执行后 PC (程序计数器) 只增加了 1,这就是单字节魅力的直观体现!

  • MUL AB也是单字节(可以认为是寄存器寻址)