8051指令系统
发布于 3/24/2026, 7:11:07 AM
微机原理
单片机的工作过程
执行一条指令可以分为取指令,分析指令和执行指令三个阶段 存在单周期与双周期的指令,也存在单字节与双字节的指令
51系列单片机指令系统
8051共111条指令,8条伪指令
- 49条单字节,双字节46条,三字节16条;
- 单周期64条,双周期45条,四周期2条
- 数据传送29条,算术运算24条,逻辑运算24条,控制转移17条,布尔操作17条.
指令格式如下: [标号]:操作码 [操作数1],[操作数2],[操作数3];[注释]
常见汇编符号:
8个工作寄存器
2个地址指针工作寄存器
#data 立即数,8位常数,16位则#data16
direct 8位片内RAM的地址,也用data表示
addr16 16位目的地址,用于LCALL&LJMP中
rel 补码形式地址偏移
bit 片内RAM可直接寻址的位地址
@ 间接寻址 取数据为地址
/ 位操作中表示位取反
注意#30H表示立即数,30H表示直接地址
寻址方式:
MOV A,#30H; 立即寻址,将立即数存入数据指针中
MOV A,30H; 直接寻址,将30H中数据存入A中
INC DPTR; 寄存器寻址,DPTR数据自增
MOVX @DPTR,A; 间接寻址,以数据指针数据为地址,将A中数据装入外部RAM中该地址
堆栈操作的PUSH POP以SP为间接地址寄存器,也是间接寻址
MOVC A,@A+PC;变址寻址,从A+PC地址取操作数
JC 03H;CY=1时,PC执行完当前指令相对跳转三个地址单元
SETB 00H;位寻址,直接将00H位设置为1
数据传输类指令
MOV :内部数据传送
MOV <目的操作数>,<源操作数>
MOV可应用场景:
- 以累加器A为目的操作数的数据传送指令
MOV A, Direct ;A←(Direct) Direct为寄存器地址或I/O端口
MOV A, Rn ;A←(Rn) n=0~7
MOV A, @Ri ;A←( (Ri) ) i=0~1
MOVC:针对ROM
- 以寄存器Rn为目的操作数的数据传送指令
MOV Rn, A ; Rn←(A)
MOV Rn, direct ; Rn←(direct)
MOV Rn, #data ; Rn← data
- 以片内RAM或端口直接地址direct为目的操作数的数据传送指令
MOV direct, A ; direct←(A)
MOV direct, Rn ; direct←(Rn)
MOV direct, #data ; direct←data
MOV direct1, direct2 ; direct1←(direct2),*机器码为逆序
MOV direct, @Ri ; direct←( (Ri) )
- 以间接地址为目的操作数的数据传送指令
MOV @Ri, A ; (Ri)←(A)
MOV @Ri, direct ; (Ri)←(direct)
MOV @Ri, #data ; (Ri)← data
- 16位数据传输指令
MOV DPTR, #data16 ;
MOVC 查表指令; move code,针对ROM
MOVC A, @A+PC ; PC当前指令的地址, A←((A)+(PC)) 变址寻址
MOVC A, @A+DPTR ; A←((A)+(DPTR)) 变址寻址
MOVX 片外数据传送(只有以下)用法
MOVX A, @DPTR ; A←((DPTR)) DPTR中的地址为16位,数据为8位
MOVX @DPTR, A ; (DPTR) ←(A) DPTR的片外寻址范围为64KB
MOVX A, @Ri ; A←((Ri)) Ri中的地址为8位,数据也为8位
MOVX @Ri, A ; (Ri) ←(A) Ri的片外寻址范围为256B
PUSH POP 堆栈操作
PUSH direct ; SP←(SP)+1 , SP←(direct) 堆栈指针上移,并压栈数据
POP direct ; direct←(SP), SP←(SP)-1 弹栈数据, 堆栈指针下移
复位上电后SP默认值为07H,(恰好第一组R7之后)
XCH,SWAP 数据交换
XCH A, Rn ; (A)←→(Rn) 数据交换
XCH A, Direct ; (A)←→(Direct) 数据交换
XCH A, @Ri ; (A)←→( (Ri) ) 间接寻址,数据交换
XCHD A, @Ri ; (A)的低4位←→( (Ri) )的低4位 低4位数据交换
SWAP A ; (A)的低4位←→ (A)的高4位
工作寄存器间不能直接进行数据传送
算术运算类指令
运算结果将影响PSW标志位:
- 若bit7有进位,CY=1。反之,CY=0。
- 若bit3有进位,AC=1。反之,AC=0。
- 若bit7和bit6有且仅有一位进位,OV=1,反之,OV=0。
同时 CY=1表示无符号和溢出,OV=1表示有符号和溢出
加法指令 ADD ADDC INC (有符号负数以补码表示)
- 不带进位的加法指令ADD,累加器A与<操作数>相加。相加的结果只能存放于累加器A中。
ADD A, Rn ; A←(A)+(Rn)
ADD A, direct ;A←(A)+(direct)
ADD A, @Ri ; A←(A)+( (Ri) )
ADD A, #data ; A← (A)+data
- 带进位的加法指令ADDC,累加器A与<操作数>及CY相加
ADDC A, Rn ; A←(A)+(Rn)+CY
ADDC A, direct ;A←(A)+(direct)+CY
ADDC A, @Ri ; A←(A)+( (Ri) ) +CY
ADDC A, #data ; A← (A)+data+CY
- 自加1指令INC (不影响标志位)
INC A ; A←(A)+1
INC Rn ; Rn←(Rn)+1
INC direct ; direct←(direct)+1
INC @Ri ; (Ri)←( (Ri) )+1
INC DPTR ; DPTR←(DPTR)+1
减法指令 SUBB DEC
- 若bit7有借位,CY=1。反之,CY=0。
- 若bit3有借位,AC=1。反之,AC=0。
- 若bit7和bit6有且仅有一位借位,OV=1,反之,OV=0。
- 带借位的减法指令SUBB,A与<操作数>相减,再减CY
SUBB A, Rn ; A←(A)-(Rn)-CY
SUBB A, direct ; A←(A)-(direct)-CY
SUBB A, @Ri ; A←(A)-((Ri))-CY
SUBB A, #data ; A←(A)-data-CY
若要不带借位,SUBB前CLR C
- 自减1指令DEC(不影响标志位)
DEC A ; A←(A)-1
DEC Rn ; Rn←(Rn)-1
DEC direct ; direct←(direct)-1
DEC @Ri ; (Ri)←( (Ri) )-1
没有DEC DPTR
乘法指令 MUL AB
- 仅针对累加器A和B寄存器中的无符号数,需4个机器周期。
- 运算乘积结果为2字节,低位存放在A中,高位存放在B中。
- 运算结果大于 00FFH,OV=1,否则OV=0。CY一定被清零。不影响AC。
除法指令 DIV AB
- 仅针对累加器A和B寄存器中的无符号数,需4个机器周期。
- 运算商存放在A中,余数存放在B中。
- 运算前B=0则OV=1,否则OV=0。CY一定被清零。不影响AC。
十进制调整指令 DA A
- 若A3~0>9或AC=1,则A←(A)+06H
- 若A7~4>9或CY=1,则A←(A)+60H
- 仅用于压缩BCD码加法运算后的调整,补充6使提前进位,heximal变成decimal
- 指令用于ADD或ADDC指令之后,不影响标志位AC和OV。若高4位加6调整后产生最高位进位,则置位CY,反之,不清零CY。
- 不能用于减法SUBB指令之后。
逻辑运算类指令
逻辑与: ANL <目的操作数>, <源操作数> ;按位取与,结果存于目的操作数
ANL A, Rn ; A←(A)·(Rn)
ANL A, direct ; A←(A)·(direct)
ANL A, @Ri ; A←(A)·( (Ri) )
ANL A, #data ; A←(A)·data
ANL direct, A ; direct←(direct)· (A)
ANL direct, #data ; direct←(direct)·data
逻辑或,按位取或,结果存于目的操作数
ORL A, direct ; A←(A)+(direct)
ORL A, @Ri ; A←(A)+( (Ri) )
ORL A, #data ; A←(A)+data
ORL direct, A ; direct←(direct)+ (A)
ORL direct, #data ; direct←(direct)+data
逻辑异或,同理
XRL A, direct ; A←(A)⊕(direct)
XRL A, @Ri ; A←(A)⊕( (Ri) )
XRL A, #data ; A←(A)⊕data
XRL direct, A ; direct←(direct)⊕(A)
XRL direct, #data ; direct←(direct)⊕data
取反,清零:
CPL A ; 累加器A按位取反。
CLR A ; 累加器A清零。
左移,右移:
RL A ;累加器A左移位
RR A ;累加器A右移位
RLC A;累加器A带进位左移位
RRC A;累加器A带进位右移位
控制转移类指令
转移到新的PC地址处继续执行
- 无条件转移指令
LJMP addr16 ; 长转移,PC指向addr16,实现64K范围内程序转移。
AJMP addr11 ; 绝对转移,双字节指令,指令取出后PC+2,之后,PC高5位不变, 低11位被addr11覆盖(2K范围,基于AJMP执行后的PC+2)。
SJMP rel ; 相对转移,双字节指令。相对于指令执行之前的PC,执行后PC=PC+2+rel。rel是有符号数,范围是-128~+127。
- 条件转移指令
判断累加器A是否为零的跳转
JZ rel ; A=0? Jump if Zero
JNZ rel ; A≠0?
比较跳转指令(判断两无符号操作数是否相等)
CJNE A, direct, rel ; A≠(direct)? Compare …Jump if Not Equal
CJNE A, #data, rel ; A ≠data?
CJNE Rn, #data, rel ; Rn ≠ data?
CJNE @Ri, #data, rel ; (Ri) ≠ data?
自减1条件跳转指令(操作数自减1)
DJNZ Rn, rel ; Rn-1=0? Decrease and Jump if Not Zero
DJNZ direct, rel ; (direct)-1=0?
- 间接转移指令
JMP @A+DPTR ; PC转移指向A+DPTR(变址寻址,目标地址在程序运行时才确定)
- 子程序调用及返回指令
LCALL addr16 ; 长调用指令,3字节
执行步骤1:PC=PC+3。
执行步骤2: PC所指的16位地址入栈(先低8位后高8 位),同时堆栈指针SP=SP+2。
执行步骤3: PC=addr16 。调用范围64kB。
ACALL addr11 ; 短调用指令,2字节
执行步骤1:PC=PC+2。
执行步骤2: PC所指的16位地址入栈(先低8位后高8 位),同时堆栈指针SP=SP+2。
执行步骤3: addr11 -> PC低11位,PC高5位保持不变。调用范围2kB。
RET ; 子程序返回指令。用于子程序的末尾。
执行步骤1:PC设置为栈顶处2个字节。这2个字节正是执行调用指令时送入堆栈的PC内容。
执行步骤2: SP=SP-2。
- 空指令NOP,消耗一机器周期
位操作类指令
位地址的表达方式
- 直接使用位地址,范围为00H~FFH。其中前128个位于字节地址20H~2FH,后128个位于SFR区。
- 字节***.*位序号,如PSW.5、P1.0、20H.7,这种表达方法限定于可位寻址的字节,例如没有30H.7
- 位的名称,如F0、RS0。
- 位数据传送指令
MOV C, bit ; bit 设置到 CY中,CY兼做布尔操作中的累加器。
MOV bit, C ; CY设置到 bit 中。
- 位修改指令
CLR C ; 清空CY为0
CLR bit ;清空bit位为0
SETB C ; 设置CY为1
SETB bit ; 设置bit位为1
CPL C ; 取反
CPL bit ; 取反
- 位逻辑运算指令
ANL C, bit ; 设置C为C·bit
ANL C, /bit ; 设置C为C·(bit取反)
ORL C, bit ; 设置C为C+bit
ORL C, /bit ; 设置C为C+(bit取反)
- 位转移指令
JC rel ; C=1, 转移; C=0, 顺序执行
JNC rel ; C=0, 转移; C=1, 顺序执行
JB bit, rel ; bit=1,转移; bit=0, 顺序执行
JNB bit, rel ; bit=0, 转移; bit=1, 顺序执行
JBC bit, rel ; bit=1, 清bit并转移; 否则,顺序执行
伪指令
- ORG <>,规定起始地址
- END 汇编结束
- 字符名 EQU 表达式,类似于宏定义,
X1 EQU 50H; 把50H数据寄存器命名为X1 - 定义字节伪指令 把指令右边的数据依次放入自标号开始的连续存储单元中。 [标号:] DB byte1, byte2, byte3…. TAB: DB 30H,49,32H,58
- 定义字(双字节)伪指令 [标号:] DW word1, word2, word3….
ORG 2000H
DW 23H,15,3628H
(2000H)=00H,(2001H)=23H
(2002H)=00H,(2003H)=0FH
(2004H)=36H,(2005H)=28H
-
定义位伪指令 字符名 BIT 位地址 例如: OCT BIT 08H
-
定义数据地址伪指令 字符名 DATA 地址