3.1.0指令系统
复杂指令集(CISC),指令长度不一❗
指令由操作码和操作数组成❗

- 42种助记符(供人类程序猿👨💻编程使用)
- 这些助记符实现33种功能
- 助记符和不同寻址方式结合,构造出111种指令
- 编译器将这些指令编译成CPU能够理解的255种操作码
这种设计使得程序员只需记住少量助记符(42种)就能编写出使用全部255种操作码的程序,大大简化了编程过程。
3.1.1 7种寻址方式❗
寻址方式就是在指令中给出寻找操作数或操作数所在地址的方法。
指令操作常伴有从右向左传送数据的内容,所以常把左边操作数称为目的操作数,而右边操作数称为源操作数。
源操作数寻址
寄存器寻址 ❗
寄存器寻址是指在指令中将指定寄存器的内容作为操作数。因此,指定了寄存器就能得到操作数。
在寄存器寻址方式中,用符号名称来表示寄存器,例如:

- 寄存器寻址的寻址范围包括:
- 4个寄存器组共32个通用寄存器
- 但在指令中只能使用当前寄存器组。因此,在使用前要通过指定PSW中的RS1、RSO,以选择使用的当前寄存器组。
- 部分特殊功能寄存器,例如累加器A、AB寄存器对以及数据指针DPTR。
- 非法指令:
直接寻址❗
- 在指令中直接给出操作数单元的地址
其功能是把片内数据储存器中3AH单元内的数据传送给累加器A

- 直接寻址方式只能给出8位地址,因此只能访问有限的区域(片内数据存储器),也就是:
- 低128位单元,在指令中直接以单元地址形式给出
- 特殊功能寄存器
- 这时除可以单元地址形式给出外,还可以寄存器符号形式给出。虽然特殊功能寄存器可以使用符号标志,但在指令代码中还是按地址进行编码的,所以也算作直接寻址
直接寻址是访问特殊功能寄存器的唯一方法
立即寻址❗
- 在指令中直接给出操作数
“#”后面的就是一个16位(H表示16进制,16进制下4位,二进制下16位)立即数,实际上就是直接对这个数操作,和“地址”没啥关系
这个“立即数”是直接和代码一起储存在程序储存器里的,如下图所示
寄存器间接寻址❗
- 寄存器间接寻址是指在指令中给出的寄存器内容是操作数的地址,从该地址中取出的才是操作数。

- 寄存器间接寻址的寻址范围:
- 片内数据存储器的低128单元。只能采用R0、R1为间接寻址寄存器
- 高128位字节被特殊功能寄存器占用,这部分不支持间接寻址
- 片外数据存储器
- 堆栈区
单片机型号 | 地址范围 80H - FFH 的内容 | 如何访问 |
80C51 | 仅有特殊功能寄存器 (SFR) | 只能用直接寻址 |
80C52 | RAM 和 SFR 地址重叠 | 寄存器间接寻址 访问 RAM
直接寻址 访问 SFR |
只支持寄存器间接寻址。其中,可以采用R0、R1寻址低256位,或者采用DPTR寻址整个64KB的片外RAM空间

位寻址❗
通常我们只能对一个字节(8个二进制位)整体操作,在特殊情况下可以对一个字节中具体的二进制位进行操作,这就是80C51的位处理功能
CLR ADDR
是一个位寻址指令。CLR是位操作指令,而这里的ADDR指的是位地址

相对寻址❗

- 相对转移指令
- 基础款:
- 进阶款(使用label(LOOP),编译时会自动算出所需的偏移量)

变址寻址❗


变址寻址指令的特点:
- 只能对程序储存器进行寻址,或者说是专门针对程序存储器的寻址方式❗,也就是只能使用MOVC命令
- 变址寻址指令只有三条:
前两条是程序读指令,后两条是无条件转移指令

目的操作数的寻址
上面所讲的各种方法都是针对源操作数的,而目的操作数也有寻址的问题

目的操作数的寻址方式只有4种方式:
- 寄存器寻址
- 直接寻址
- 寄存器间接寻址
- 位寻址
3.1.2 指令格式❗
一条指令通常由操作码和操作数两部分构成
- 操作码用来规定指令所完成的动作
- 操作数表示具体的对象
- 如3.1.1所述,操作数可能是一个具体的数据,也可能是指出取得数据的地址或符号
单片微机中,指令都是不定长的变长指令
单字节指令
指令只有一个字节,操作码和操作数同在一个字节中。在80C51系列的指令系统中,共有49条单字节指令。

双字节指令
双字节指令包括两个字节。其中一个字节为操作码,另一个字节是操作数。在80C51系列的指令系统中,共有45条双字节指令。

MOV A共用一个字节(操作码+目的操作数),立即数占一个字节(源操作数)
三字节指令
在三字节指令中,操作码占一个字节,操作数占两个字节。其中操作数既可能是数据,也可能是地址。在80C51系列的指令系统中,共有17条三字节指令。

典型指令的指令长度和执行时间❗
指令类型 (按长度) | 典型执行时间 (机器周期) | 长度 (字节) | 示例 |
单字节指令 | 1 | 1 | INC A, CPL A, NOP |
ㅤ | 2 | 1 | INC DPTR , MOVX A, @Ri, RET |
ㅤ | 4 | 1 | MUL AB , DIV AB |
双字节指令 | 1 | 2 | ADD A, #data, MOV A, 30H |
ㅤ | 2 | 2 | SJMP rel, JNZ rel, DJNZ R0, loop |
三字节指令 | 2 | 3 | LJMP addr16, LCALL addr16, MOV 30H, #5AH |
NOTE THAT:
PPT上给出了以下推论:两个操作数的指令长度必定是3个字节,执行时间是2个机器周期
基本可以确定是错的,因为MOV A, R0也有两个操作数,但是指令长度1个字节;
但是3个字节指令执行时间是2个机器周期没有问题
3.1.3 指令分类
指令→操作码+操作数
指令停留在编程的层面,而操作码是编译之后的机器语言的层面
111种指令,却有255种操作码,是因为寻址方式不同
可能在编程语言上完全相同的指令,但是在寻址方式不同导致它使用的是两个操作码

3.1.4 指令系统中的符号说明

