510 likes | 729 Views
4 MCS-51 指令系统. 【 几个概念 】 指令系统: 一台计算机的 CPU 所能执行的指令集合。 机器语言: 采用二进制编码表示的指令,是计算机能够直接识别和执行的语言。 汇编语言: 采用助记符、符号、数字来表示指令的程序语言,它与机器语言指令是一一对应的。 汇编语言程序: 采用汇编语言编制完成特定功能的汇编语言指令逻辑的集合。亦称 汇编语言源程序 ,不同于 汇编程序 。. 1. 概述. 1 )指令格式 标号:操作码助记符 [( 目的操作数 ) , ( 源操作数 )] ;注释.
E N D
【几个概念】 • 指令系统: • 一台计算机的CPU所能执行的指令集合。 • 机器语言: • 采用二进制编码表示的指令,是计算机能够直接识别和执行的语言。 • 汇编语言: • 采用助记符、符号、数字来表示指令的程序语言,它与机器语言指令是一一对应的。 • 汇编语言程序: • 采用汇编语言编制完成特定功能的汇编语言指令逻辑的集合。亦称汇编语言源程序,不同于汇编程序。
1.概述 • 1)指令格式 • 标号:操作码助记符 [(目的操作数),(源操作数)] ;注释 2)MCS-51单片机指令系统的分类 • A. MCS-51单片机指令系统按指令所占的字节数可分为以下三类: • (1)单字节指令(49条)(2)双字节指令(45条) • (3)三字节指令(17条) • B. 按指令的执行时间可分为以下三类: • (1)单周期指令(64条) (2)双周期指令(45条) • (3)四周期指令(2条)(乘、除指令)
C. 按指令的功能可分为以下五类: • (1) 数据传送类指令(29条) • (2) 算术运算类指令(24条) • (3) 逻辑运算及移位类指令(24条) • (4) 控制转移类指令(17条) • (5) 位操作类指令(17条) • 111条基本指令共派生出255种指令代码00H~FFH(其中A5H无定义) • 例如: • MOV A,Rn • (n=0~7,代码:E8H~EFH)
3)指令中的常用符号 (P.53) • Rn : 表示当前工作寄存器R0~R7中的一个。 • @Ri : 表示寄存器间接寻址,常常作间接寻址的地址指针。其中Ri只代表R0和R1寄存器中的一个。 • Direct : 表示内部数据存贮器RAM单元的地址及特殊功能寄存器SFR的地址,对SFR而言,既可使用它的物理地址,也可直接使用它的名字。 • #date : 表示8位立即数,即8位常数,取值范围为#00H~#0FFH。 • #date16: 表示16位立即数,取值范围为#0000H~#FFFFH。 • addr16: 表示16位地址。
指令中的常用符号(续) • addr11: 表示11位地址。 • Rel : 用补码形式表示的地址偏移量,取值范围为-128~+127。 • Bit : 表示内部RAM和SFR中的具有位寻址功能的位地址。SFR中的位地址可以直接出现在指令中,往往也可用SFR的名字和所在的数位表示。如:表示PSW中奇偶校验位,可写成D0H,也可写成PSW.0的形式出现在指令中。 • @ : 表示间接寻址寄存器标识符。 • / :位操作数的前缀,表示对该位操作数取反,如/bit。 • (x) :表示x单元中的内容。 • ((x)) :表示以x单元中的内容为地址进行间接寻址。 • $ : 表示当前指令的地址。
2.数据传送类指令 • 数据传送类指令共28条,是将源操作数送到目的操作数。指令执行后,源操作数不变,目的操作数被源操作数取代。数据传送类指令用到的助记符有MOV、MOVX、MOVC、XCH、XCHD、SWAP、PUSH、POP 8种。 • 源操作数可采用寄存器、寄存器间接、直接、立即、变址5种寻址方式寻址,目的操作数可以采用寄存器、寄存器间接、直接寻址3种寻址方式。一般均不影响标志位C、AC、OV,但不包括P。MCS-51单片机片内数据传送途径如图所示。
直接地址 direct 累加器 A 直接地址 direct 间接地址 @Ri 寄存器 Rn 立即数 #data 数据指针 DPTR MCS-51单片机片内数据传送图
1)以累加器A为目的操作数 2)以工作寄存器Rn为目的操作数
3)以直接寻址为目的操作数(内部RAM单元或SFR寄存器)3)以直接寻址为目的操作数(内部RAM单元或SFR寄存器) 例:MOV A,4FH ;RAM的4FH单元内容送A MOV A,#4FH ;立即数送A MOV 4FH,#4FH ;立即数送RAM的4FH单元
4)以间接寻址为目的操作数 例如:设(30H)=6FH,R1=40H,执行MOV @R1,30H后,30H单元中数据取出送入R1间接寻址的40H单元,(40H)=6FH。 5)16位数据传送指令(唯一的16位数据一次传送指令)
6)外部数据传送指令 7)查表指令 例1:已知A=30H,DPTR=3000H,ROM中(3030H)=50H,执行 MOVC A,@ A+DPTR 后,A=50H。 例2:(书P61)
例:设内部RAM(30H)=40H,(40H)=10H,P1口输入0CAH(11001010B)。例:设内部RAM(30H)=40H,(40H)=10H,P1口输入0CAH(11001010B)。 • 执行: • MOV R0,#30H ;(R0)←#30H • MOV A,@R0 ;(A) ←(30H) • MOV R1,A ;(R1) ←(A)=40H • MOV B,@R1 ;(B) ←(40H)=10H • MOV @R1,P1 ;(40H) ←#0CAH • MOV P2,P1 ;(P2) ←#0CAH • 执行完后,(R0)=30H,(A)=(R1)=40H • (B)=10H,(40H)=0CAH,(P2)=0CAH
8)累加器传送类指令 例:设(R0)=20H,(A)=3FH,(20H)=75H, 执行:XCH A,@R0 结果:(A)=75H,(20H)=3FH。 例:(R0)=20H,(A)=36H,(20H)=75H, 执行:XCHD A,@R0 结果:(A)=35H,(20H)=76H 执行:SWAP A 结果:(A)=63H
片内RAM 片内RAM 片内RAM 片内RAM 40H 50H 40H 50H 40H 40H 34H ×× 30H 30H 30H 30H ×× 11H 50H 34H 11H 11H 11H 34H SP ×× ×× ×× ×× 10H 10H SP 10H 10H 执行前 执行前PUSH指令后 执行前 执行POP指令后 SP SP 9)堆栈操作指令 PUSH 40H POP 30H
√堆栈区由特殊功能寄存器堆栈指针SP管理 √堆栈区可以安排在 RAM区任意位置,一般不安排在工作寄存器区和可按位寻址的RAM区,而是放在RAM区的靠后的位置 √堆栈总是指向栈顶 √通常PUSH与POP两条指令成对使用 例:设(A)=7BH,(35H)=11H,并且(SP)=60H,(60H)=35H。 PUSH ACC ;(61H) #7BH PUSH 35H ;(62H) (35H) ;即:(62H) #11H POP ACC ;(A) (62H) 即:(A) #11H POP 5AH ;(5AH) (61H) 即:(5AH) #7BH POP SP ;数据出栈,(SP)-1→(SP),后再进栈, (SP)+1→(SP),((原SP))=(60H)=35H→((SP)),执行后(SP)=60H。先SP指针减1为5FH,后装入由栈顶退出的值,原栈顶内容35H送堆栈。
方法1(直接地址传送法): MOV 31H,30H MOV 30H,40H MOV 40H,31H SJMP $ 【例】将片内RAM 30H 单元与 40H 单元中的内容互换。 • 方法3(字节交换传送法): • MOV A,30H • XCH A,40H • MOV 30H,A • SJMP $ • 方法2(间接地址传送法): • MOV R0,#40H • MOV R1,#30H • MOV A,@R0 • MOV B,@R1 • MOV @R1,A • MOV @R0,B • SJMP $ • 方法4(堆栈传送法): • PUSH 30H • PUSH 40H • POP 30H • POP 40H • SJMP $
3.算术运算类指令(*ALU部件仅执行无符号二进制整数的算术运算)3.算术运算类指令(*ALU部件仅执行无符号二进制整数的算术运算) • 1)加法指令 标志位影响:AC、C、OV、P 例:(A)=0C3H,(R0)=0AAH,执行:ADD A,R0 结果:和=6DH,AC=0,C=1,OV=1。 注:当无符号数运算时OV无意义。
2)带进位加法指令 标志位影响:AC、C、OV、P 注:分两步,先(A)+(C),再与源操作数相加,最后得结果。常用于多字节相加。 例:设(A)=0C3H,(R0)=0AAH, (C)=1,执行:ADDC A,R0, 结果:和=6EH,存于A, AC=0,C=1,OV=1。
【例】 试把存放在 R1 R2 和 R3 R4 中的两个16位数相加,结果存于 R5 R6 中。 • 解:参考程序如下: • CLR C • MOV A,R2 ;取第一个数的低8位 • ADD A,R4 ;两数的低8位相加 • MOV R6,A ;保存和的低8位 • MOV A,R1 ;取第一个数的高8位 • ADDC A,R3 ;两数的高8位相加,并把低8位相加时 • 的进位位加进来 • MOV R5, A ;把相加的高8位存入R5寄存器中 • SJMP $
3)带借位减法指令 标志位影响:AC、C、OV、P 例1:设(A)=0C9H,(R2)=54H,(C)=1 执行: SUBB A,R2 结果:(A)=74H,AC=0,C=0,OV=1 注:在进行单字节或多字节减法前,如C未 知,应先清C;OV在无符号数运算时无意义。
例2:多字节减法 • 设被减数和结果存于R0间址单元,减数存于R1间址,字节数存于R2单元,要求对结果的溢出位检查,溢出则转向YC。 • 程序: • CLR C ;清C • JF: MOV A,@R0 ;被减数送A • SUBB A,@R1 ;(A)-(C)-((R1)) • MOV @R0,A ;结果存R0 • INC R0 ;指向下一个被减数 • INC R1 ;指向下一个减数 • DJNZ R2,JF ;(R2)-1=0,结束循环 • JB OV,YC ;判跳,OV=1跳,否则往下运行 • …… • YC: …… • 注:此程序可以看作是比较两个多字节数的大小问题。
4)BCD码修正指令 DA A • 把A中按二进制相加的结果调整成按BCD码相加的结果,如 • (A0~3)>9或(AC)=1,则(A0~3)+06H→ (A0~3), • 如(A4~7)>9或(C)=1,则(A4~7)+60H→(A4~7) • 注: • 本指令紧跟在加法指令后。 • 本指令不能简单的把16进制数变换成BCD码。 • 本指令是对BCD码加法结果进行调整,两个压缩型BCD码相加后必须经本指令调整后才得到压缩型BCD码得和数。本指令不能进行二~十进制减法的调整。 • 在调整过程中,如果产生最高进位,则置C,反之,不清C;这时C的置位表示和数BCD码大于100。适用于多字节十进制加法。 • 不影响OV位。
例1:(A)=65BCD,(B)=78BCD,C=0,执行下列语句:例1:(A)=65BCD,(B)=78BCD,C=0,执行下列语句: • ADD A,B • DA A • 后,得(A)=43 BCD,C=1,表示结果是143。 • 例2:BCD码的减1操作可用加#99H来求得,条件是不计进位位。(相当于以模#100D计算) • 设(A)=30BCD, • 执行: • ADD A,#99H • DA A • 得:结果(A)=29H,C=1不计。 • 注:主要运用十六进制数得模为16。
例3:6位BCD码相加 • 设被加数存于RAM的32H、31H、30H单元,加数存于42H、41H、40H单元,和存于52H、51H、50H单元,已转换为BCD码。检查进位标志C位。 • 程序: • MAIN: CLR C • MOV A,30H • ADD A,40H • DA A • MOV 50H,A • MOV A,31H • ADDC A,41H • DA A • MOV 51H,A • MOV A,32H • ADDC A,42H • DA A • MOV 52H,A • JC YC ;C=1跳转 • ……
例4:十进制减法 • 设压缩型BCD码的减数存于符号地址MINUEND单元,减数存于SUBSTR,结果存于RES单元。 • 注:MCS-51没有十进制减法指令,必须采用补码相加的方法,用#9AH减去减数即得以十为模的补码。亦即#100D为模。 • 程序: • MAIN: CLR C ;清C • MOV A,#9AH • SUBB A,SUBSTR ;求减数的补码 • ADD A,MINUEND ;补码相加 • DA A ;BCD码调整 • MOV RES,A ;得结果,送RES • CLR C
5)加1指令 • 例:书P.64例1、例2。 • 注: • 不影响标志位。 • 如原值为0FFH,执行指令后为00H。 • DPTR是唯一一个能进行增量操作的16位寄存器。 • 如果对I/O口加1时,操作时针对端口的锁存器,而不是从引脚读入。
6)减1指令 • 注: • 不影响标志位。 • 如原值为00H,执行指令后为FFH。 • DPTR是唯一一个能进行减1操作的16位寄存器。 • 如果对I/O口减1时,操作时针对端口的锁存器,而不是从引脚读入。
7)乘法指令 • MUL AB ;BA← A×B • A和B中各存放一个8位无符号数,指令执行后,16位乘积的高8位在B中,低8位存A中,清C和OV;乘积>255(0FFH),OV置1。 • 例1:A=30H,B=60H,执行 MUL AB 后,A=00H,B=12H。 • 例2:书P.68例2。 8)除法指令 DIV AB ;A÷B→商在A中,余数在B中 A和B中各存放一个8位无符号数,A放被除数,B放除数。指令执行后,A中存放商,B中存入余数,清C和OV。若B=00H,则指令执行后OV=1,清C,A与B不变。 例如,A=30H,B=07H,执行 DIV AB 后,A=06H,B=06H。
例:16位数(双字节)相乘。 • 分析:设被乘数高、低字节为XH和XL,乘数为YH和YL,则乘积为 • ( XH ×28+XL)× ( YH ×28+YL)=( XH ×28+XL)× YH ×28+ ( XH ×28+XL)×YL • 根据上式,两个16为数相乘可化为乘数的高、低字节分别与被乘数相乘,两个乘积错位一个字节相加,其和为两个16位数相乘的结果。对应的程序可组织成两重循环结果,其内循环完成8位数与16位数相乘,并将乘积累加和加到结果单元。结果占4个单元。 • 入口: • RLADR单元:结果最低字节; • XRADR单元:被乘数最低字节,XLADR-1存放被乘数高字节; • YDH单元:存放乘数高字节 • YDL单元:存放乘数低字节
程序: • DMUL:MOV R4,YDDL ;乘数低字节送R4 • MOV R3,#2 ;外循环次数送R3 • DMUL1: MOV R2,#2 ;内循环次数送R2 • MOV R1,RLADR ;结果低字节地址送R1 • MOV R0,XLADR ;被乘数最低字节地址 送R0 • DMUL2: MOV A,@R0 ;被乘数送A • MOV B,R4 ;乘数送B • MUL AB • ADD A,@R1 ;乘积的字节加到结果单元 • MOV @R1,A • DEC R1 ;R1指向高一个字节结果地址 • MOV A,B ;乘积高字节B→A
ADDC A,@R1 ;乘积高字节与结果单元相加 • MOV @R1,A ;存结果单元 • DEC R1 ;R1指向高一个字节结果单元 • CLR A • ADDC A,@R1 ;将进位加到结果单元 • MOV @R1,A • INC R1 ;结果单元地址加1 • DEC R0 ;R0指向被乘数的高一个字节 • DJNZ R2,DMUL2 ;判内循环2次完成否? • MOV R4,YDH ;乘数高字节送R4 • DEC RLADR • DJNZ R3,DMUL1 ;跳回DMUL1进行双字节被乘数和 高字节乘数相乘
4.逻辑运算类指令 • 1)逻辑与运算指令 例1:(A)=0C3H,(R0)=0AAH,执行 ANL A,R0 得(A)=82H 例2:用ANL来屏蔽某些不用位。方法:将该位用“0”相“与”,目的操作数常用直接寻址方式,源操作数用立即数。 如:ANL P1,#01100110B。
2)逻辑或运算指令 例1:(A)=0C3H,(R0)=55H,执行ORL A,R0 得(A)=0D7H 例2:用ORL可置某些位。方法:将需置位得位与“1”相“或”,目的操作数常是直接寻址方式,源操作数是立即数。 如:ORL P1,#00110010B。
3)逻辑异或运算指令 例1: (A)=0C8H,(R0)=0AAH,执行XRL A,R0 得(A)=69H 例2:用XRL来对某些位取反。方法:将需取反得位与“1”相“异或”,目的操作数常是直接寻址方式,源操作数是立即数。 如:XRL P1,#00110001B。 例3:可用XRL来判断两个数是否相等。相等,结果为全“0”。
4)循环移位指令 5)清零、取反指令
01011101 01011101 01011101 1 01011101 1 • 例1:(A)=55H(01011101B),C=1 • 执行 • CLR A (A)=00000000H • CPL A (A)=10100010H • RL A (A)=10111010H • RLC A (A)=10111011H,C=0 • RR A (A)=10101110H • RRC A (A)=10101110H,C=1
6)空操作指令 例:书P.82 7)子程序调用与返回指令 • RET用于子程序返回和RETI用于中断服务子程序。 • RETI能告知中断系统,中断服务子程序已执行结束,恢复中断逻辑以接受新的中断请求。而RET只能结束子程序,不能结束中断逻辑。
绝对调用ACALL: • ACALL为双字节,可寻址空间:包含当前指令(即调用指令的下一条指令)的第一个字节在内的2K字节范围内的程序存储器中(即与其高5位地址相同)。 • 在执行ACALL时,PC的高5位(PC11~15)保持不变。A10a9a83位为页地址,a0~7为页内地址,即256个单元为一页。 • 例:(SP)=07H,符号地址“SUBSTR”为0345H,在(PC)=0123H处执行 ACLL SUBSTR 结果:(PC)+2=0123H+2=0125H,压栈, (SP)+1=07H+1=08H,(08H)=25H, (SP)+1=08H+1=09H,(09H)=01H, SUBSTR=0345H送PC,(PC)=0345H,程序转向0345H执行。
长调用LCALL: • 后者为三字节,可寻址空间:64K字节程序存储器空间的任何位置。 • 例:(SP)=07H,符号地址”SUBSTR“为5678H,在(PC)=0123H处执行 LCALL SUBSTR 结果:(PC)+3=0123H+3=0126H,压栈, (SP)+1=07H+1=08H,(08H)=26H, (SP)+1=08H+1=09H,(09H)=01H, SUBSTR=5678H送PC,(PC)=5678H,程序转向5678H执行。 如果在子程序中执行RET,则SP,PC的值?
5.位操作类指令 • 1)位数据传送指令 • 2)位置位、取反指令
例1:C=1,P3 口的输入数据为1100 0101B,P1口的输出数据为0011 0101B,执行 MOV P1.3,C MOV C,P3.3 MOV P1.2,C • 结果:C=0,P3口不变,P1为0011 1001B。 • 例2:P. 88例2实现两个存储器高低位相反的情况。通过移位,送C,后通过位传送达到。 • 例3:C=0,P1口为0011 0100B SETB C SETB P1.0 • 例:执行下列指令,数据如例3: CPL P1.0 CPL P1.4 • 得:P1口0010 0101B
例:编写一段程序,实现如图的逻辑功能。 • 其中,U、V是P1.1、P1.2的状态,W为Timer0的溢出中断请求标志位TF0,X为中断1标志IE1,Y、Z是20H.0、21H.1位,输出Q为P3.3。 • 程序: • U:BIT P1.1 • V:BIT P2.2 • W:BIT TF0 • X:BIT IE1 • Y:BIT 20H.0 • Z:BIT 21H.1 • Q:BIT P3.3 • MIAN:MOV C,V ORL C,W ANL C,U MOV F0,C MOV C,X ORL C,/Y ANL C,F0 ANL C,/Z MOV Q,C
4)位条件转移指令 注:1.前4条指令对bit位的测试不影响原变量。 2.执行完JBC指令后,不管该变量为何值,检测后bit位 都为“0”。
例1:C=0 执行 JC LABEL1 CPL C ;C=1 JC LABEL2 … • LABEL2:JNC LABEL3 CPL C ;C=0 JNC LABEL4 … • 结果:程序转向LABEL4。 • 例2:设(A)=01010110H,(P1)=11001010B。 • 1. JB P1.2,LABEL1 JNB A.3,LABEL2 2. JBC A.3,LABEL3 JBC A.4,LABEL4 ;(A.4)=0
6.控制转移类指令 • 1)无条件转移指令 • 绝对(短)转移指令 • AJMP addr11 ;PC10~0 ← addr11 • ——可在指令所在的2K范围内跳转 • 长转移指令 • LJMP addr16 ;PC ← addr16 • ——可在64K范围内跳转 • 短(相对)转移指令 • SJMP rel ;PC ← PC + 2 + rel ——可在当前PC值-128与+127范围内跳转 • 间接转移指令 • JMP @A+DPTR ;PC ← A + DPTR • ——可在以DPTR为基址 + A为偏移量之和所 指向的64K程序范围内跳转
例1:设(rel)=FEH,执行 • JMPD:SJMP JMPD • (因为FEH为补码,真值是-2,则目的地址PC=PC+2-2,转向自己,程序在原处无限循环。此方法常用于程序暂停。) • 例2:设A中的内容为0~6之间的偶数。实现多分支选择转移指令。 • MOV DPTR,#JMP-TBL • JMP @A+DPTR • … • JMP-TBL:AJMP L0 • AJMP L1 • AJMP L2 • AJMP L3 注:1.分支表长度不能超过256字节 2.与其他三条指令相比,前者转移的目标地址在汇编时是已知的,本指令的目标地址是动态的,是以DPTR为起始的256字节单元。 3.如目标地址超过64K,程序从0000H往下延续,即以216为模。
2)条件转移指令 • 累加器为零(非零)转移指令 • JZ rel ;当(A)=“0”,(PC)=(PC)+rel • JNZ rel ; 当(A)≠“0”,(PC)=(PC)+rel • 循环转移指令 • DJNZ Rn(或direct),rel;(PC)←(PC)+2 • (Rn)←(Rn)-1,(Rn)≠0则转移 • 比较转移指令 • CJNE (目的字节),(源字节),rel ;影响标志位C • 相对偏移量rel的求法 • MCS-51系列rel经汇编后在代码中用偏移量的补码表示,以加法代减法