指令字节和指令周期
指令字长有三种:
单字节 RET
双字节 MOV A, #68H
三字节 MOV 30H, 46H
指令周期是指执行一条指令所需要的时间
- 1机器周期指令
- 2机器周期指令
- 4机器周期指令
4.3.1 数据传送指令:
1、内部8位数据传送指令
- mov A,#data ;(A)<--- #data
- mov A, data ;(A)<--- (data)
- mov A, @Ri ;(A)<--- ((Ri)) i=0,1
- mov A,Rn ;(A)<--- (Rn) n=0~7
- mov Rn,# data;(Rn ) <--- #data
- mov Rn, data ;(Rn) <--- (data)
- mov Rn,A ;(Rn) <--- (A)
【例4-14】MOV A, 40H ; (A)<---(40H)
MOV A, #40H ; (A)<---40H
注意 40H 和#40H的区别
【例4-15】MOV A, Rl ; (A)<---(R1)
MOV A, @Rl ; (A)<---((R1))
注意 @R1 和R1的区别
【例4-16】MOV 90H, #40H ;(P1)<---40H
MOV P1, #40H ;(P1)<---40H
MOV R0, #90H ;(R0)<---90H
MOV @R0, #40H ;(90H)<---40H
注意:
(1) 目的操作数不能采用立即寻址。
(2) @Ri中的i范围为0和1。
(3) Rn中的n的范围为0~7。
(4) 每条指令中最多只能有1个Rn或@Ri。
【例4-17】 以下指令都是错误的。
MOV #30H, 40H
MOV A, @R2
MOV R1, R3
MOV R1, @R0
MOV @R1 , R2
MOV @R0, @R1
【例4-18】
MOV A, 60H ;(A)<---(60H),目的操作数为寄存器寻址
MOV 0E0H, 60H ;(A)<---(60H),目的操作数为直接寻址
MOV 09H, #40H ;(09H)<---40H,目的操作数为直接寻址
MOV R1, #40H ;(R1)<---40H,目的操作数为寄存器寻址
【例4-19】 分析程序的执行结果。
设内部RAM中30H单元的内容为80H,试分析执行下面程序后各有关单元的容。
MOV 60H, #30H ;(60H)<---30H
MOV R0, #60H ;(R0)<---60h
MOV A, @R0 ;(A)<---30H
MOV R1, A ;(R1)<---30H
MOV 40H, @R1 ;(40H)<---80H
程序执行结果为:(A)=30H,(Ro)=60H,(R1)=30H, (60H)=30H,(40H)=80H,(30H)=80H
2和3、外部数据传送指令
【例4-20】 将内部RAM 80H单元的内容送入外部RAM 70H单元。程序如下:
MOV R0,#80H
MOV A,@R0
MOV R0,#70H
MOVX @R0,A
此例中访问内部RAM和访问外部RAM均通过R0间接寻址,不同的是访问内部RAM用操作码MOV,访问外部RAM使用操作码MOVX,二者不能混淆。
4、交换指令
- XCH A, Rn ; (A) <=> (Rn), n=0~7
- XCH A,direct; (A)<=> (direct)
- XCH A, @Ri; (A)<=> ((Ri)) ,i=0,1
- XCH D A,@Ri ; (A) 0~3 <=> ((Ri))0~3
- SWAP A ; (A) 0~3 <=> (A)4~7
【 例4-22】 设(A)=34H , (R3)=56H, 执行指令:
XCHA, R3
则结果为: (A)=56H, (R3)=34H
【例4-23】 设(A)=34H , (R0)=30H, (30H)=56H, 执行指令:
XCHD A, @RO
则结果为: (A)=36H, (30H)=54H
5、查表指令
MOVC A, @A+PC ;(PC)<---(PC)+1;(A)<---((A)+(PC))
MOVC A, @A+DPTR ;(A)<---((A)+(DPTR))
【例4-24 】 执行程序:
地址 指令
0F00H MOV A,#30H
0F02H MOVC A,@A+PC
.
.
.
0F33H 3FH
.
.
.
实现将程序存储器0F33H 单元内容3FH送入A的功能。
【例4-25 】 执行程序:
MOV DPTR, #2000H
MOV A, #30H
MOVC A, @A+DPTR
实现将程序存储器中2030H单元的内容送入累加器A的功能。
6、堆栈操作指令
-PUSH direct ; ( sp ) <---(sp)+1, ( (sp))<--- (direct)
-POP direct ; ( direct ) <---((sp)) ,(sp)<--- (sp)-1
- 堆栈:一种数据结构,是“先进后出“线性表。
- 堆栈操作: 压入 PUSH , 弹出 POP
- 堆栈区: 占片内RAM 中连续的存储单元
复位后, 系统自动将SP指针指向07H
用户可将堆栈区设在30H ---7FH 数据缓冲区内,
如: MOV SP,#5FH
堆栈两种类型: 向上生长型和向下生长型, 如图2-5 所示。向上生长型堆栈,栈底在低地址单元。随着数据进栈, 地址递增, S P 的内容越来越大, 指针上移; 反之, 随着数据的出栈, 地址递减, SP 的内容越来越小, 指针下移。如(b)图所示。
MCS-51属向上生长型堆栈,这种堆栈的操作规则如下:
进栈操作: 先SP加1,后写入数据。
出栈操作: 先读出数据,SP减1 。
向下生长型堆栈, 栈底设在高地址单元。随着数据进栈, 地址递减, SP内容越来越小, 指针下移; 反之, 随着数据出栈, 地址递增, SP内容越来越大,指针上移。其堆栈操作规则与向上生长型正好相反。如(a)图所示。
堆栈的使用有两种方式:
一种是自动方式, 即在调用子程序或断点时, 断点地址自动进栈。程序返回时,断点地址再自动弹回PC。这种操作无需用户干预。
另一种是指令方式, 即使用专用的堆栈操作指令, 执行进出栈操作, 其进栈指令为PUS H, 出栈指令为POP。 例如:
保护现场就是一系列指令方式的进栈操作;
而恢复现场则是一系列指令方式的出栈操作。
需要保护多少数据由用户决定。
【例4-26】 设(SP)=70H,(ACC)=50H,(B)=60H ,
执行下述指令:
PUSH ACC ;(SP)<---(SP)+1,(71H)<---(ACC)
PUSH B ;(SP)<---(SP)+1,(72H)<---(B)
结果为:(71H)=50H, (72H)=60H,(SP)=72H
此例中ACC和B都是用直接寻址方式寻址的,不能用寄存器寻址方式。入栈指令常用于保护CPU现场等场合。
【例4-27】 设(SP)=72H,(72H)=60H,(71H)=50H,
执行下述指令;
POP DPL ;DPL((SP)),(SP)<---(SP)-1
POP DPH ;DPH((SP)),(SP)<---(SP)-1
结果为: (DPTR)=5060H,(SP)=70H
4.3.2 算术运算指令
1、加法指令
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, 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)
.
2、带借位的减法指令
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)
3、加1指令
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
4、减1指令
DEC A ; (A) (A)-1
DEC Rn ; (Rn) (Rn)-1
DEC direct ; (direct) (direct)-1
DEC @Ri ; ((Ri)) ((Ri))-1
【例4-33】 试分析执行以下程序后, 各有关单元的结果。
解:程序如下:
MOV R1, #7FH
MOV 7EH, #00H
MOV 7FH, #40H
DEC @R1
DEC R1
DEC @R1
执行结果: (R1)=7EH (7EH)=0FFH (7FH)=3FH
【例 4-32】 设20H~21H单元存放一个16位二进制数X1(高8位存于21H单元),30H~31H单元存放另一个16位二进制数X2(高8位存于31H单元)。求X1+X2,和存于20H~21H ,设两数之和不超过16位。解:程序如下:
ORG 2000H
MOV R0, #20H
MOV R1, #30H
MOV A, @R0 ; 取被加数低8位
ADD A, @R1 ; 求和的低8位
MOV @RO, A ; 存和的低8位
INC R0 ; 指向被加数高8位
INC R1 ; 指向加数高8位
MOV A, @R0 ; 取被加数高8位
ADDC A, @R1 ; 求和的高8位
MOV @R0,A ; 求和的高8位
SJMP $ ;停机
END
运算结果:高8位存于21H单元,低8位存于20H单元。
5、十进制调整指令
DA A ; 若(AC)=1 或(A)3~0>9,则A<---(A)+06H
;若(Cy)=1 或(A)7~4>9,则A<---(A)+60H
•调整原则:形式上非BCD码 需要加 06H、60H、66H调整
-形式上是BCD码时: CY AC 调整原则
0 0 不调整
0 1 +06H
1 0 +60H
1 1 +66H
【例4-34】 编写程序完成78+93的BCD码加法程序, 并对调整过程进行分析。解: 相应BCD码加法程序为:
ORG 3000H
MOV A, #78H ; (A)<---78H
ADD A, #93H ; (A)<---78H+93H=0BH
DA A ; (Cy)=1, (A)=0BH; 加66H调整
SJMP $
END
执行结果: (A)=71H ,考虑进位标志(Cy)=1 ,操作结果为171。
6、乘法指令
MUL AB ; (A)<---(A) X (B)低字节, (B )<---( A) X (B)高字节
指令功能: 把累加器A和寄存器B中两个8位无符号二进制数相乘, 积的低8位存在累加器A中, 积的高8位存在B寄存器中。运算结果将对Cy、OV、P标志位产生如下影响:
- 进位标志位Cy总是清 '' 0'' ;
- P标志仍为A累加器的奇偶校验位;
- 当积大千255(B中的内容不为0)时, 则(OV)=1,否则OV=0。
【例4-35】 设(A)=80H ,(B)=2DH, 执行指令:
MUL AB
结果为 (A)=80H , (B)=16H, (OV)=1, (Cy)=0, (P)=1
7、除法指令
DIV A B ;(A<---(A)/(B)(商), (B)<---(A)/(B)(余数)
该指令把累加器A中的8位无符号整数除以寄存器B中8位无符号整数, 所得商存在A中, 余数存在B中。对标志位的影响如下:
(1)对Cy和P标志的影响与乘法时相同;
(2)当除数为0时, 除法没有意义, (OV)=1 , 否则OV=0,表示除法操作是合理的。
【例4-35】 设(A)=OB6H ,(B)=0FH,执行指令:
DIV AB
结果为:
(A)=0CH, (B)=02H, (OV)=0, (Cy)=0, (P)=0
4.3.3 逻辑运算指令
1、逻辑“与“运算指令
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
【例4-37】 将累加器A中的压缩BCD码拆成二个字节的非压缩BCD码, 低位
放入30H, 高位放人31H单元中。 程序如下:
PUSH ACC ;保存A中的内容
ANL A, #0FH ;清除高4位, 保留低4位
MOV 30H, A ;低位存人30H
POP ACC ;恢复A中原数据
SWAP A ;高、低4位互换
ANL A, #0FH ;清除高4位, 保留低4位
MOV 31H, A
2、逻辑“或“运算指令
ORLA, Rn ;(A)<---(A) V(Rn)
ORLA, direct ;(A)<---(A)V(direct)
ORLA, @Ri ;(A)<---(A)V((Ri))
ORLA, #data ;(A)<---(A) V#data
ORL direct,A ;(direct)<---(direct)V(A)
ORL direct,#data ;(direct)<---(direct) V #data
【例4-38】 编制程序把累加器A中低4位送入P1口低4位,P1口高4位不变。程序如下:
ANL A, #0FH ;取出A中低4位, 高4位为0
ANL P1, #0F0H ;使P1口低4位为0, 高4位不变
ORL P1, A ;
3、逻辑“异或“运算指令
XRL A, Rn ; (A) <---(A)⊕(Rn)
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
4、累加器A清0、取反指令
CLR A ; A<---0: 累加器A清0,不影响标志位。
CPL A ; A<---累加器A的内容按位取反,不影响标志位
5、累加器A移位指令
RL A ;累加器左环移
RLC A ;累加器通过Cy左环移
RR A ;累加器右环移
RRC A ;累加器通过Cy右环移
【例4-40】 执行下面的程序段, 观察累加器A中内容的变化。
MOV A, #01H ;(A)<---01H
RL A ;(A)<---02H
RL A ;(A)<---04H
RL A ;(A)<---08H
【例4-41】 编制程序将M1 、M1 +1 单元中存放的16位二进制数扩大到二倍。(设该数低8位在M1单元中, 扩大后小于65536)。
CLR C ;(Cy)<---0
MOV R0,#Ml ;操作数低8位地址送
RO MOV A,@R0 ;(A)操作数低8位
RLC A ;低8位操作数左移,低位补0,最高位在Cy中
MOV @R0,A ;送回M1 单元
INC R0 ;R0指向M1+1单元
MOV A,@R0 ;(A)<---操作数高8位
RLC A ;高8位操作数左移,M1最高位通过Cy移入最低位
MOV @R0,A ;送回M1+1单元
4.3.4 控制转移类指令
-无条件转移指令
-条件转移指令
- 调用/返回指令
-空操作指令
1、无条件转移指令
- 16位地址的无条件转移指令
- 11位地址的无条件转移指令
- 相对转移指令
- 散转指令
2FFFH AJMP L1
当前(PC)=2FFFH+2=300 lH
转移地址 ( PC )=00110XXX XXXXXXXX
保持高5位不变, L1地址标号范围 3000H~37FFH
若L1=35BCH(5页),则指令码为A1BCH
3)相对转移指令
SJMP rel ;(PC)<---(PC)+2, (PC)<---(PC)+rel
rel为地址偏移量,为带符号8位二进制数,常用补码表示,范围为 -128~+127,因此, 程序转移范围为当前PC前128字节, 或后127字节。
【例4-41】 程序中等待功能常由以下指令实现:
HERE: SJMP HERE
或: SJMP $
指令中偏移量rel在汇编时自动算出为OF EH, 即-2的补码, 执行后目标地址就是本指令的起始地址。
4)散转指令
JMP @A+DPTR ; (PC)<---(A)+(DPTR)
本指令将累加器A中的8位无符号数与16位数据指针相加, 其和装入程序计数器PC,控制程序转向目标地址
【例4-43】设累加器A中存放待处理命令的编号(0~n;n<=85 )程序存储器中存放着标号为PGTB的转移表,则执行以下程序,将根据A内命令编号转向相应的命令处理程序。
PG:MOV B,#3 ; A (A)*3 MULAB
MOV DPTR, #PGTB ;DPTR转移表首址
JMP @A+DPTR
PGTB: LJMP PG0 ; 转向命令0处理入口,LJMP PG0 为三字节指令
LJMP PG1 ;转向命令1处理入口
.
.
.
LJMPPGn
2、条件转移指令
1)累加器判零转移指令
JZ rel ; 若(A)=0, 则 ( PC )<---(PC)+2+ rel 累加器为0转移
; 若(A)≠0, 则 (PC)<---(PC)+2
JNZ rel ; 若(A)≠0 , 则(PC)<---(PC)+2+rel 累加器不为0转移
; 若(A)=0, 则(PC)<--- (PC)+2
2)比较转移指令
格式 CJNE <目的字节>,<源字节>, rel
指令功能:目的字节与源字节比较,比较的值不等则转移,相等则按顺序执行程序。
若目的字节< 源字节, 则 (Cy)= 1 , 否则(Cy)= 0。 本 指令执行后不影响指令中的任何操作数。
比较转移指令共有四条: CJNE A,#data,rel CJNE A,direct,rel CJNE @Ri,#data,rel CJNE Rn,#data,rel
【例4-44】
CJNE R4,#35H,NEQ ;(R4)≠35H转移
EQ: … ;(R4)=35H处理程序
┇
NEQ: JC LESS ;(R4)<35H转移
LAG: … ;(R4)>35H处理程序
┇
LESS: … ;(R4)<35H处理程序
3)循环转移指
DJNZ Rn, rel ;(Rn)<---(Rn)-1
若(Rn)=0,则(PC)<---(PC)+ 2
若(Rn)≠0, 则(PC)<---(PC)+2 + rel
DJNZ direct, rel ;(direct)<---(direct)-1
若(direct)=0, 则(PC)<---(PC)+ 3
若(direct)≠0, 则(PC)<---(PC)+3 + rel
【例4-45】 编制程序, 将内部RAM 70H字节起始的16个数送外部RAM1000H字节起始的16个单元。
MOV R7, #16 ;数据长度送R7
MOV R0, #70H ;数据块起始地址送RO
MOV DPTR, #1000H ;存放区起始地址送DPTR
LOOP: MOV A, @R0 ;从内RAM取数据
MOVX @DPTR , A ;数据送外RAM
INC R0 ;修改数据地址
INC DPTR ;修改存放地址
DJNZ R7, LOOP ;数据未送完,则继续送,否则结束
3、调用/返回指令
当CPU执行主程序到A处遇到调用子程序ADDl的指令时,CPU自动把B处,即下一条指令第一字节的地址(PC值,称为断点)压入堆栈中,栈指针(SP)+2,并将子程序ADDl的起始地址送入PC。于是,CPU就转向子程序ADDl去执行。当遇到ADDl中的RET指令时,CPU自动把断点B的地址弹回到PC中,于是,CPU又 回到主程序继续往下执行。当主程序执行到C处又遇到调用子程序ADDl的指令时, 便再次重复上述过程。
4、空操作指令 NOP ; (PC)<---(PC)+1
4.3.5 位操作(布尔处理)指令
位传送指令
位修正指令
位逻辑运算指令
位条件转移指令
1、位传送指令
MOV C , bit ; (Cy)<---(bit)
MOV bit, C ; (bit) <---(Cy)
2、位修正指令
位修正指令包括位清0、位置l和位取反。
(1)位清0指令
CLR C ; (Cy) <---0
CLR bit ; (bit)<---0
(2)位置l指令
SETB C ; (Cy)<---1
SETB bit ; (bit)<---1
(3) 位取反指令
CPL C ;(Cy)<---(/Cy)
CPL bit ;(bit)<---(/bit)
3、位逻辑运算指令
位逻辑运算指令包括按位”与“和按位”或“。
(1)按位 ” 与” 指令
ANL C, bit ; (Cy)<---(Cy)A(bit)
ANL C, /bit ; (Cy)<---(Cy)A(/bit)
双字节指令, 功能是把位累加器Cy中的内容与指定位中的内容或其反码 ” 与“, 结果在Cy中
(2)、按位 ” 或“指令
ORL C, bit ; (Cy)<---(Cy)V(bit)
ORL C, /bit ; (Cy)<---(Cy) V(/bit)
双字节指令, 功能是把位累加器Cy中的内容与指定位中的内容或其反码 ” 或“, 结果在Cy中。
4、位条件转移指令
(1)判布尔累加器C转移指令
JC rel ; 若Cy=1 , 则(PC)<---(PC)+2+rel
;若Cy=0, 则(PC)<---(PC)+2
JNC rel ;若Cy=0,则(PC)<---(PC)+2+rel
; 若Cy=1,则(PC)<---(PC)+2
(2)判位变量转移指令
JB bit, rel ;若(bit)=1 ,则 (PC)<---(PC)+3+rel
;若(bit)=0,则 ( PC )<---(PC)+3
JNB bit, rel ;若(bit)=0,则 ( PC )<---(PC)+3+ rel
;若(bit)=1,则 (PC)<---(PC)+3
(3)判位变量并清0转移指令
JBC bit, rel
; 若(bit)=1 ,则 ( PC )<---(PC)+3+rel,且 (bit)<---0
; 若(bit)=0,则 ( PC )<---(PC)+3
关于rel
机器语言中:rel 是[-128 ,+127]内的补码
汇编语言中:rel的书写形式:
1、jc loop ;loop使目标地址
2、jc $-5 ; $-5 也代表目标地址
3、jc -5 ;是相对偏移量
4、jc +5
5、jc 85H ;