第四章 指令系统及汇编语言程序设计
任课教师:刘忠国 山东大学课程中心网站: http://course.sdu.edu.cn/G2S/stcmcu.cc 网站:http://www.mcu001.com keil μvision软件下载及指导手册(Help→μvision Help) http://www.keil.com/ 何宾STC单片机原理及应用 > http://www.gpnewtech.com/study/stc/
第四章 指令系统及汇编语言程序设计 本章学习目标 了解助记符、指令格式 掌握单片机寻址方式 掌握单片机指令系统 掌握单片机汇编语言程序设计及开发环境 00:53:26
第四章 指令系统及汇编语言程序设计语言 4.1 编程语言 4.2 指令格式及其分类 4.3 寻址方式 4.4 数据传送类指令 4.4 数据传送类指令 4.5 逻辑操作类指令 4.6 算术运算类指令 4.7 位操作指令 4.8 控制类转移指令 4.9 汇编语言程序设计 4.10 汇编语言程序调试 4.11利用ISP工具将程序下载到单片机中验证程序 00:53:26
§4.6算术运算类指令 (24条) 该类指令主要完成加、减、乘、除四则运算,以及增量、 减量和二十进制调整操作。除增量、减量指令外,大多 数算术运算指令会影响到状态标志寄存器PSW。 表4-3 算术运算类指令对标志的影响 指令助记符 影响标志 备注 CY OV AC ADD(加) × “×”表示可置1或清“0”, “0”表示总清“0” ADDC(带进位加) SUBB(带借位减) MUL(乘) DIV(除) DA(二十进制调整) INC DEC 00:53:26
4.6.1 加减运算指令 (12条) 在加减运算指令中,以累加器A为第一操作数,并存放 操作后的结果。第二操作数可以是立即数、工作寄存 器、寄存器间接寻址字节或直接寻址字节。 运算结果会影响溢出标志OV、进位CY、辅助进位AC 和奇偶标志P。 1、加法指令:(4条) ADD A, #data8 ;A←A+#data8 ADD A, addr8 ;A←A+(addr8) ADD A, @Ri ;A←A+(Ri) ADD A, Rn ;A←A+Rn 把源字节变量与累加器相加, 结果保存在累加器中。 00:53:26
溢出标志OV取决于带符号数运算,和的第6、 7位中有一位产生进位而另一位不产生进位, 则使OV置1,否则OV被清0。OV=1产生溢出。 1、加法指令:(4条) 例如, MOV A, #0C3H ADD A, #0AAH 运算后,CY=1, OV=1, AC=0, A=6DH, PSW=85H 溢出标志OV取决于带符号数运算,和的第6、 7位中有一位产生进位而另一位不产生进位, 则使OV置1,否则OV被清0。OV=1产生溢出。 1100 0011 + 1010 1010 10110 1101 位号 D7 D6 D5 D4 D3 D2 D1 D0 符号 CY AC F0 RS1 RS0 OV F1 P 1 0 0 0 0 1 0 1 00:53:26
2、带进位加法指令 (4条) ADDC A, #data8 ;A←A+#data 8 +CY ADDC A, addr8 ;A←A+(addr8) +CY ADDC A, @Ri ;A←A+(Ri) +CY ADDC A, Rn ;A←A+Rn +CY 除了相加时把进位位也加上外,其他与一般加法指 令完全相同。 1010 1010 + 0101 0101 1111 1111 + 1 10000 0000 例, 设累加器A内容为0AAH, R0内容为55H, C内容为1, 执行指令: ADDC A, R0 运行结果: A=0000 0000B, AC=1,CY=1,OV=0 00:53:26
2、带进位加法指令(4条) 低字节 高字节 【例4-4】设双字节加法中,被加数放20H、21H单元,加 数放30H、31H单元,和存放在40H、41H单元,若高字 节相加有进位则转OVER处执行。试编程实现之。 解:程序代码如下: (21H) (20H) +(31H) (30H) (41H) (40H) ADDM: MOV A, 20H ;取低字节被加数 ADD A, 30H ;低位字节相加 MOV 40H, A ;结果送40H单元 MOV A, 21H ;取高字节被加数 ADDC A, 31H ;加高字节和低位来的进位 MOV 41H, A ;结果送41H单元 JC OVER ;若有进位,则转OVER处执行 …… OVER: …… 00:53:26
3、带借位减指令(4条) SUBB A, #data8 ;A←A– #data8– CY SUBB A, addr8 ;A←A–(addr8) –CY SUBB A, @Ri ;A←A – (Ri) –CY SUBB A, Rn ;A←A – Rn –CY 在加法中,CY=1表示有进位,CY=0表示无进位; 在减法中,CY=1则表示有借位,CY=0表示无借位。 0000 0011 - 1000 0000 1000 0011 OV=1表示带符号数相减时, 从一个正数中减去一个负 数得出了一个负数(如3H-80H)或从一个负数中减去一 个正数时得出一个正数的错误情况(如80H-2H) 。 和加法类似, 该标志也是由运算时,差的第6、7位两者借 位状态经异或操作而得。 因减法只有带借位减一条指令, 所以在首次进行单字节 相减时, 须先清借位位CY, 以免相减后结果出错。 结果超出了符号数的表示范围 00:53:26
3、带借位减指令(4条) 例如,设累加器A的内容为D9H,R0的内容为87H, 求两者相减结果。 CLR C SUBB A, R0 执行结果:A=52H,CY=0,OV=0 若运算两数为无符号数,则其溢出与否和OV状态无 关,而靠CY是否为1予以判别,OV仅表明带符号数运 算时是否溢出。 若是带符号数 D9H 1101 1001 – 1000 0111 0101 0010 -27H -79H - 87H 52H 00:53:26
3、带借位减指令(4条) 低字节 高字节 【例4-5】 两字节数相减, 设被减数放在20H、21H单元, 减数放在30H、31H单元, 差放在40H、41H单元。若 高字节相减有借位则转OVER处执行, 试编程实现之。 解:程序代码如下: SUBM: CLR C ;低字节减之前借位CY清0 MOV A, 20H ;被减数送A SUBB A, 30H ;低位字节相减 MOV 40H, A ;结果送40H单元 MOV A, 21H ;被减数高字节送A SUBB A, 31H ;高字节相减 MOV 41H, A ;结果送41H单元 JC OVER ;若有借位, 则转OVER处执行 …… OVER: …… (21H) (20H) - (31H) (30H) (41H) (40H) 00:53:26
4.6.2 乘除运算指令(2条) 乘除运算指令在累加器A 和寄存器B之间进行,运算 结果保存在累加器A和寄存器B中。 1、乘法指令(1条) 4.6.2 乘除运算指令(2条) 乘除运算指令在累加器A 和寄存器B之间进行,运算 结果保存在累加器A和寄存器B中。 1、乘法指令(1条) 乘法指令: MUL AB 把累加器A 和寄存器B中的8位无符号整数相乘; 16位乘积低字节在累加器A中,高字节在寄存器B中; 若乘积大于255 (0FFH), 则溢出标志位置 “1”, 否则清 “0”, 运算结果总使进位标志CY清“0” 。 乘法指令可以竖式表示: 00:53:26
1、乘法指令(1条) 例如,设A=82H(130),B=38H(56),执行指令: MUL AB 结果: 乘积为1C70H (7280), A=70H, B=1CH,OV=1, CY=0 [例4-6] 用单字节乘法指令进行多字节乘法运算。设双字 节数低8位存放在30H, 高8位存放在31H单元, 单字节数 存放在40H单元, 编程实现双字节乘以单字节的运算, 乘 积按由低位到高位依次存放在50H, 51H, 52H单元中。 解:双字节数乘以单字节数, 设双字节数用X表示, 单字节 数用Y表示,则其乘法可表示为: ( X2·28+X1 )·Y=X2·Y·28+X1·Y (31H) (30H) × (40H) (52H)(51H)(50H) 00:53:26
利用MUL指令分别进行X2·Y和X1·Y的乘法运算,然 后把等号右边两项移位相加即得其积。 可以使用下面的竖式表示: ( X2·28+X1 ) · Y=X2·Y·28+X1·Y 利用MUL指令分别进行X2·Y和X1·Y的乘法运算,然 后把等号右边两项移位相加即得其积。 可以使用下面的竖式表示: 其中, “(X1Y)低” 表示的是X1和Y乘积的低8位, 其他符号代表的含义类似。 RES0就是“(X1Y)低” , 即最后结果的最低位; RES1是“(X1Y)高 + (X2Y)低”(的结果; RES2是“(X2Y)高” 和由“(X1Y)高 + (X2Y)低” 产生的进位相加的结果。 00:53:26
[例4-6]程序代码 (X2·28+X1)·Y=X2·Y·28+X1·Y (31H) (30H) (52H)(51H)(50H) MOV A, 30H MOV B, 40H MUL AB ;X1·Y MOV 50H, A ;积低字节存50H MOV 51H, B ;积高字节存51H MOV A, 31H MUL AB ;X2·Y ADD A, 51H ;X2·Y低8位与X1·Y高8位相加作为积的第二字节 MOV 51H, A MOV A, B ;乘积最高字节送A以便与低位进位C相加 ADDC A, #00H ;最高字节加低位进位C MOV 52H, A ;最高字节存52H单元 52H, 51H, 50H 00:53:26
2、除法指令(1条) 除法指令: DIV AB 该指令把累加器A中的8位无符号整数除以寄存器B中8 位无符号整数, 所得结果的商放在累加器A中,余数在 寄存器B中, 标志位CY和OV均清“0” 。 注意:若除数(B中内容)为00H, 则执行后结果为不定值,并置位溢 出标志OV。 例, 设累加器内容为147(93H), B寄存器内容为13(0DH), 则执行命令: DIV AB 执行结果:A=0BH,B=04H,OV=0,CY=0 00:53:26
4.6.3 增量、减量指令(9条) 增量指令完成加1运算,减量运算完成减1运算。 这两条指令均不影响标志位(INC A, DEC A 影响标志P)。 1、增量指令(5条) INC A ;A ← A+1 INC addr8 ;(addr8) ←(addr8) +1 INC @Ri ;(Ri) ← (Ri) +1 INC Rn ;Rn ← Rn+1 INC DPTR ;DPTR ← DPTR+1 00:53:26
1、增量指令(5条) 注意: INC指令将指定变量加1,结果送回原地址单元, 原来内容若为0FFH,加1后将变成00H,运算结果不 影响任何标志位(INC A 影响奇偶标志位P)。 例如,设R0=7EH,内部数据RAM中 (7EH) =0FFH, (7FH) =40H,则执行指令: INC @R0 ; (7EH) ← 00H INC R0 ;R0 ← R0+1,执行后,R0=7FH INC @R0 ; (7FH) ← 41H 00:53:26
2、减量指令(4条) DEC A ;A ← A - 1 DEC addr8 ;(addr8) ←(addr8) - 1 (DEC A 影响奇偶标志位P) DEC A ;A ← A - 1 DEC addr8 ;(addr8) ←(addr8) - 1 DEC @Ri ;(Ri) ← (Ri) - 1 DEC Rn ;Rn ← Rn - 1 注意: DEC指令将指定变量减1, 结果送回原地址单元, 原内容若为00H, 减1后变成0FFH, 不影响任何标志位。 (DEC A 后A中还是偶数个1, 不影响P) 例如程序: MOV R1, #7FH ; (R1) ← 7FH MOV 7EH, #00H ; (7EH) ← 00H MOV 7FH, #40H ; (7FH) ← 40H DEC @R1 ; (7FH) ← 3FH ← 40H -1 DEC R1 ; (R1) ← 7EH← 7FH -1 DEC @R1 ; (7EH) ← 0FFH ← 00H -1 00:53:27
4.6.4 二——十进制的加法的调整指令(1条) DA指令使用说明 指令如下: DA A 该指令的调整条件和方法: 4.6.4 二——十进制的加法的调整指令(1条) 指令如下: DA A 该指令的调整条件和方法: 若A3-0>9或AC=1, 则A3-0←A3-0+06H; 若A7-4>9或CY=1, 则A7-4←A7-4+6H(A7-0←A7-0+60H)。 若两个条件同时满足或者A7-4=9且低4位修正有进位, 则A7-0←A7-0+66H。 87 1000 0111 + 0110 1000 1110 1111 + 0110 0110 10101 0101 68 DA指令使用说明 是对二——十进制加法进行调整的指令。 两个压缩型BCD码按二进制数相加, 须经本条指令调整 后才能得到压缩型的BCD码和数(可用87H+68H测算)。 CY 00:53:27
DA指令使用说明 因指令要用AC、CY等标志位才能起到正确的调整作 用, 因此它需跟在加法(ADD, ADDC)指令后面使用。 若该指令前无加法指令, (不)能用DA A完成累加器A内 容的二十进制转换。 对用户而言,只要保证参加运算的两数为BCD码, 并先 对BCD码执行二进制加法运算(用ADD, ADDC指令), 然后紧跟一条DA A指令即可。 DA A指令不能对减法进行十进制调整。 DA指令不清除标志位C, 若高4位有进位, 则置C为1, 否则, 不改变进位标志C。 00:53:27
4.6.4 二——十进制调整指令 低字节 [例4-7] 设计6位BCD码加法程序。设被加数在内部RAM 中32H, 31H, 30H单元, 加数在42H, 41H,40H单元, 相加和 放在52H, 51H, 50H单元, 忽略加后最高位进位(溢出)。 解:程序代码如下: BCDADD:MOV A, 30H ;第一字节加 ADD A, 40H DA A MOV 50H,A ;存第一字节和(BCD码) MOV A, 31H ;第二字节加 ADDC A, 41H DA A MOV 51H, A ;存第二字节和(BCD码) MOV A, 32H ;第三字节加 ADDC A, 42H DA A MOV 52H,A ;存第三字节和(BCD码) (32H)(31H)(30H) +(42H)(41H)(40H) (52H)(51H)(50H) 00:53:27
4.6.4 二——十进制调整指令 【例4-8】假设有两个十进制数,被减数保存在30H单 元,减数保存在40H单元。编程实现二者的减法运算, 结果存50H单元中。 解: 利用十进制加法调整指令作十进制减法调整, 必须 采用补码相加的方法, 用9AH(即十进制的100)减去减 数即得以10 (100)为模的减数补码。程序代码如下: BCDSUB:CLR C ;清进位位 MOV A, #9AH ;求减数补码 SUBB A, 40H ADD A, 30H ;进行补码相加 DA A MOV 50H, A ;结果(差)存50H单元 讨论: 被减数大于减数时, 结果容易理解; 被减数小于减数时, 结果可看成向百位借位而得到的结果; 或将A再求补码即得绝对值: (9AH-(A)); 再处理符号位(见下页) 参见4.9 节 “多字节十进制BCD码减法” 00:53:27
§4.7 位操作指令(17条) 位操作指令以位作为处理对象, 可完成位传送、位状 态控制、位逻辑操作、位条件转移等功能, 共17条。 可被指令识别的位地址表示方式有如下几种: 直接用位地址(十进制或十六进制数)表示,或写成位 地址表达式表示。 写成字节地址加位数方式表示,二者之间用“.”号隔 开。例如0B8H.0 (IP.0),20H.1等。 位寄存器的定义名称,如C (PSW.7)、EA (IE.7)等。 对位寻址寄存器, 可用字节寄存器名加位数来表示, 二者之间用“.”号隔开。例如P1.0,PSW.4等。 用户使用伪指令事先定义过的符号地址。 00:53:27
表4-4 位操作指令的操作码助记符及对应的操作数 §4.7 位操作指令(17条) 表4-4 位操作指令的操作码助记符及对应的操作数 操 作 功 能 操作码 操作数 备注 位传送 MOV C, bit 或 bit, C 源地址和目的地址可互换 位状态控制 位清零 CLR C或 bit bit表示直接寻址位 位取反 CPL 位置位 SETB 位逻辑操作 与 ANL C⊕bit→ C C⊕/bit→ C ⊕表示做某种运算, /bit表示直接寻址位的非 或 ORL 位跳转 判C判移 JC rel rel为相对偏移量 JNC 判直接寻址位转移 JB bit,rel JNB为“0”转移,JB为“1”转移 JNB JBC 寻址位为1转移并清“0”该位 00:53:27
4.7.1 位传送指令(2条) MOV C, bit ; CY ← (bit) MOV bit, C ;(bit) ← CY 指令功能:是把第二操作数所指出的布尔变量传送到 由第一操作数指定的位单元中。 其中一个操作数必为位累加器(进位标志CY),另一个 可以是任何直接寻址位(bit)。 指令执行结果不影响其他寄存器或标志位。 例如, 设内部数据RAM中(20H)=79H,执行指令: MOV C, 07H ;07H是位地址, 即字节地址20H单元内容的第7位位置, ;指令将使CY=0。 0111 1001 20H CY 00:53:27
4.7.2 位状态控制指令(6条) 位状态控制指令包括位的清“0”、取反和置位。 1、位清“0”指令 (2条) 4.7.2 位状态控制指令(6条) 位状态控制指令包括位的清“0”、取反和置位。 1、位清“0”指令 (2条) CLR bit ;(bit) ← 0 CLR C ; CY ← 0 上述指令可使直接寻址位(bit)或位累加器CY清“0”, 不影响其他标志。 设内部RAM字节地址25H单元内容为34H (0011 0100B), 执行指令: CLR 2AH ;2AH为字节地址25H第2位的位地址 ;将使25H单元的内容变为30H(0011 0000B) 图3-10 字节地址25H的位地址 00:53:27
4.7.2 位状态控制指令(6条) 2、位求反指令(2条) CPL bit ;(bit) ← ( ) CPL C ; CY ← 4.7.2 位状态控制指令(6条) 2、位求反指令(2条) CPL bit ;(bit) ← ( ) CPL C ; CY ← 上述指令可把直接寻址位(bit)或位累加器CY 内容取反,不影响其他标志。 例如,执行指令序列: MOV 25H, #5DH ;(25H)=0101 1101B CPL 2BH ;(25H)=0101 0101B CPL P1.2 ; P1.2求反 图3-10 字节地址25H的位地址 00:53:27
4.7.2 位状态控制指令(6条) 3、位置位指令(2条) SETB bit ;(bit)← 1 SETB C ; CY ← 1 4.7.2 位状态控制指令(6条) 3、位置位指令(2条) SETB bit ;(bit)← 1 SETB C ; CY ← 1 上述指令把任何可寻址的位或进位标志CY置1, 不影响其他标志。 例如,P1口原已写入了49H(0100 1001B),则执 行 SETB P1.7 ;将使P1口输出数据变为C9H(1100 1001B)。 00:53:27
4.7.3 位逻辑操作指令(4条) 1、位逻辑与指令(2条) ANL C, bit ; CY ← CY∧(bit) ANL C, /bit ; CY ← CY∧( ) 将直接寻址位内容或直接寻址位内容取反后(原内容不 变)与位累加器CY进行逻辑“与” 操作, 结果存在CY中。 “/bit”表示对该寻址位内容取反后再进行位操作。 位逻辑 “与” 操作示意图如图示。 例:ANL C, /OV /OV OV 图4-7 a) ANL C, bit指令示意图 b) ANL C, /bit指令示意图 00:53:27
2、位逻辑或指令(2条) ORL C, bit ;CY ← CY ∨(bit) ORL C, /bit ;CY ← CY ∨(/bit) 上述指令将直接寻址位的内容或直接寻址位的内容取 反后(不改变原寻址内容)与位累加器CY进行逻辑 “或”操作,结果保存在CY中。 例:ORL C, /OV 位逻辑“或” 操作的示意图如图示。 /OV OV 图4-8 ORL指令逻辑示意图 00:53:27
位逻辑与、或指令举例 例如,编程实现: 当位地址(7FH)=1并且累加器中 (ACC.7)=1时, 进位位C置1, 否则C清0 , 可用ANL指 令实现。 可编程序如下: MOV C, 7FH ;CY←(7FH) ANL C, ACC.7 ;CY←CY∧ ACC.7 例, 将位地址7FH中的内容和累加器ACC.7中的内容相 “或”的程序(只要两个位的任一位为1则C为1)如下: MOV C, 7FH ORL C, ACC.7 ;相“或”的结果存CY中 00:53:27
4.7.4 位条件转移指令(5条) 位条件转移指令分为判CY转移和判直接寻址位状态 转移两种。 1、判CY转移指令(2条) 4.7.4 位条件转移指令(5条) 位条件转移指令分为判CY转移和判直接寻址位状态 转移两种。 1、判CY转移指令(2条) JC rel ; 若CY= 1,则PC←PC+rel,否则顺序执行 JNC rel ; 若CY= 0,则PC←PC+rel,否则顺序执行 上述两条指令通过判进位CY的状态决定程序的走向, 前一条若进位标志为1(后一条若进位标志为0)就可使 程序转向目标地址,否则顺序执行下一条指令。 目标地址为第二字节中的带符号的偏移量rel与PC的 当前值(PC←PC+2)之和,不影响任何标志。 (rel 一般用符号地址) 00:53:27
1、判CY转移指令(2条) JC rel指令操作过程如图a) JNC rel指令操作过程如图b) (rel 一般用符号地址) 程序flash PC→ PC+1→ PC+2→ 1、判CY转移指令(2条) 1005H 40H 1006H rel 1007H JC rel指令操作过程如图a) JNC rel指令操作过程如图b) 现行的PC 下一指令地址 (rel 一般用符号地址) PC+rel (a)JC rel指令(机器码:40H rel) (b) JNC rel 指令(机器码:50H rel) 图4-9 JC指令和JNC指令执行示意图 00:53:27
1、判CY转移指令(2条) 在实际应用中,一般在rel的位置写入欲跳转到的标号 地址,偏移量由汇编程序自动进行计算。这样做有两 个好处,一是程序的可读性好,二是不必进行偏移量 的计算。 例如,程序段: ADD A, #30H ; 加法指令,影响标志位C JC L2 ;若C=1(有进位), 则转L2, 否则, 继续执行 L1: …… L2: …… 00:53:27
2、判直接寻址位转移指令(3条) JB bit, rel ;若(bit) =1, 则PC←PC+rel JNB bit, rel ;若(bit) =0, 则PC←PC+rel JBC bit, rel ;若(bit) =1, 则PC←PC+rel, 且 (bit) ←0 ;若条件不满足, 指令顺序执行。 三条指令操作过程分别如图a)、图b)和图c)所示。 (rel 一般用符号地址) Bit=1? PC←PC+rel (bit) ←0 Y N PC←PC+3 Bit=1? PC←PC+rel Y N PC←PC+3 Bit=0? PC←PC+rel Y N PC←PC+3 a) JB bit,rel 指令 b) JNB bit,rel 指令 c) JBC bit,rel 指令 00:53:27
2、判直接寻址位转移指令(3条) 应用中,一般在rel的位置写入欲跳转到的标号地址, 偏移量由汇编程序自动进行计算。例如,指令序列: MOV P1, #0CAH ;P1←0CAH (1100 1010B) MOV A, #56H ;A←56H (0101 0110B) JB P1.2, L1 ;因P1.2=0, 不转L1, 而继续执行下条指令 JNB ACC.3, L2 ; ACC.3=0 转L2处执行 L1: …… L2: …… 00:53:27
2、判直接寻址位转移指令(3条) 另一段程序: MOV A, #43H ;A← 43H(0100 0011B) JBC ACC.2, L1 ;因ACC.2=0, 不转L1,而继续执行下条指令 JBC ACC.6, L2 ;ACC.6=1 转L2执行, 且ACC.6← 0 L1: …… L2: …… 两段程序执行后均使程序转向L2处,但前段程序转移后 维持原变量ACC.3=0不变,后段程序却把原变量 ACC.6=1清0。 转移到L2后的A(0000 0011B) 00:53:27
§4.8 控制转移类指令 (17条) 使程序不按存放顺序执行, 而转到另外的地址去执行。 包括两种:程序转移指令、子程序调用和返回指令。 §4.8 控制转移类指令 (17条) 使程序不按存放顺序执行, 而转到另外的地址去执行。 包括两种:程序转移指令、子程序调用和返回指令。 转移指令和调用指令的区别 转移指令只是跳转到新地址去,不再跳转回来; 调用指令只是暂时转到新的地址(子程序)处执行一段指令,执行完这一段指令以后再跳转回来,按照调用之前的顺序继续执行程序。 所以,调用指令要具有能够跳转回来并能够能继续执行调用之前程序的功能,这些功能都是借助堆栈(保护断点)的操作实现的。 00:53:27
表4-5 控制转移类指令(17条) (4条) (2条) 类 别 功 能 操作数 备注 无条件转移 长转移 LJMP addr16 类 别 功 能 操作码 助记符 操作数 备注 无条件转移 长转移 LJMP addr16 addr16表示16位地址 绝对转移 AJMP addr11 Addr11指低11位地址数 相对短转移 SJMP rel rel带符号的8位相对偏移量 间接转移 JMP @A+DPTR A中是8位无符号数 条件 转移 判零转移 JZ rel JNZ 比较转移 CJNE [A,Rn,@Ri], #data8, rel A, addr8, rel (4条) 循环转移 DJNZ Rn, rel addr8, rel (2条) 子程序调用 和返回 长调用 LCALL addr16 绝对调用 ACALL addr11 子程序返回 RET 转移(调用)地址一般用符号地址) 其他 中断返回 RETI 空操作 NOP 00:53:27
1、程序转移指令(12条) (1)无条件转移指令 (4条) 长转移指令 LJMP 绝对转移指令 AJMP 相对短转移指令 SJMP (2)条件转移指令 (8条) 累加器判零转移指令(JZ, JNZ) (2条) 比较转移指令 (CJNE) (4条) 循环转移指令 (DJNZ) (2条) 00:53:27
1、程序转移指令(12条) (1)无条件转移指令(4条) 无条件转移指令,是使程序不按照指令的存放顺序 执行,而是无条件转到另一处执行的指令,该类指 令不影响标志位。 实质上,无条件转移指令就是控制程序计数器PC从 现行值转移到目标地址。 长转移指令 LJMP addr16 绝对转移指令 AJMP addr11 相对短转移指令 SJMP rel 间接转移指令 JMP @A+DPTR 00:53:27
(1)无条件转移指令(4条) 1)长转移指令 LJMP addr16 ;PC←addr16 因直接提供16bit目标地址, 所以执行该指令可使程序从 当前地址转移到64KB程序存储器空间任何地址单元。 例如,如果在程序存储器0000H单元存放一条指令 LJMP 0100H 执行结果:复位后程序将跳到0100H单元去执行。 00:53:27
(1)无条件转移指令(4条) 2)绝对转移指令 a10~a8 AJMP addrll 机器码: xxx00001 addr7~0 ;PC←PC+2,PC15~11不变,PC10~0←addr10~0 第二字节存放的是低8位地址,第一字节5、6、7 位存放着高3位地址a10~a8。 注意:AJMP为双字节指令,当程序真正转移时PC 值已加2,因此,目标地址应与AJMP后面相邻指令 的第一字节地址在同一2KB范围内。 如果超过了2KB范围,汇编程序会提示出错。本指令 不影响标志位。 机器码: xxx00001 addr7~0 a10~a8 00:53:27
(1)无条件转移指令(4条) 3)相对短转移指令 SJMP rel ;PC←PC+2,PC←PC+rel 因而目标地址可以在这条指令首地址的前128字节到 后127字节之间。 00:53:27
(1)无条件转移指令(4条) 4)间接转移指令 JMP @A+DPTR ; PC←A+DPTR 执行16位加法时,从低8位产生的进位将传送到高 位去。 指令执行后不影响累加器和数据指针中的原内容, 不影响任何标志。 00:53:27
4)间接转移指令 JMP @A+DPTR ; PC←A+DPTR 这是一条极其有用的多分支选择转移指令,其转移 地址是在程序运行时动态决定的,这也是和前3条指 令的主要区别。 因此,可在DPTR中装入多分支转移程序的首地址, 而由累加器A的内容来动态选择其中的某一个分支 予以转移, 这就可用一条指令代替众多转移指令,实现以DPTR 内容为起始的256个字节范围的选择转移。 00:53:27
(1)无条件转移指令(4条) LJMP 、AJMP、 SJMP 在实际应用中,由于AJMP和SJMP指令的跳转范围 有限,而LJMP(长转移指令)不受跳转范围的限制, 因此,一般情况下都可使用LJMP指令代替AJMP和 SJMP指令。 L2 ; 转L2去执行 L1: …… L2: …… LJMP AJMP SJMP JMP 转移地址一般用符号地址, 直观易懂, 不易出错(包括下面条件转移指令) 00:53:27
(2)条件转移指令(8条) 条件转移指令,是以执行该指令时的状态标志为条件, 决定是否改变程序执行的顺序。符合条件就转移;不 符合条件就不转移,顺序执行指令。 条件转移指令属于短距离相对转移,适用于与绝对地 址无关的程序,跳转范围以当前地址为中心的-128~ +127字节之内。若转移距离超过短距离范围,则必须 使用两级以上的跳转。 条件转移指令有: 累加器判零转移指令(JZ, JNZ) (2条) 比较转移指令 (CJNE) (4条) 循环转移指令 (DJNZ) (2条) 00:53:27
(2)条件转移指令(8条) 1)累加器判零转移指令(2条) JZ rel (一般用符号地址); 若累加器为0则转移 JNZ rel (一般用符号地址); 若累加器不为0则转移 均为双字节,其中第二条字节为带符号的相对偏移 量,PC现行值(PC加2后)与偏移量相加即得转移地 址。该指令不改变累加器内容,不影响标志位。 A≠0? PC←PC+rel Y N PC←PC+2 A=0? PC←PC+rel Y N PC←PC+2 图4-12 JZ和JNZ指令执行示意图 JZ rel JNZ rel 00:53:27
1)累加器判零转移指令(2条) 例如,执行程序: MOV A, P0 ; P0口内容送累加器A JZ L1 ; A=0, 则跳转L1去执行 DEC A ; A减1 L1: …… 00:53:27
2)比较转移指令(4条) CJNE (目的字节), (源字节),rel 比较转移指令有4条: CJNE A, #data8,rel (一般用符号地址) 比较转移指令有4条: CJNE A, #data8,rel CJNE A, addr8,rel CJNE @Ri, #data8, rel CJNE Rn, #data8, rel 该指令比较前面两个操作数的大小,如果它们的值不 相等则转移,相等则继续执行。 三字节指令,PC当前值(PC+3 → PC)与指令第三 字节带符号的偏移量相加即得到转移地址。 对进位位CY有影响: 如果目的字节的无符号整数值小 于源字节的无符号整数值,则置位进位标志,否则清 “0”进位位,指令不影响任何一个操作数。 00:53:27
比较转移指令的操作过程 取完CJNE指令时 (rel 一般用符号地址) 图4-14 CJNE指令执行流程示意图 A, addr8, L2 ; 转L2执行 L2: …… A, addr8, A, #data8, Rn, #data8, @Ri, #data8, CJNE (rel 一般用符号地址) 转移地址一般用符号地址, 直观易懂, 不易出错 图4-14 CJNE指令执行流程示意图 00:53:27
2)比较转移指令(4条) 例, 设(R7)=53H, 执行下列指令(判断两数的大小) CJNE R7, #68H, K1 ;由于(R7)≠68H, 转K1, 且CY←1 (因(R7)<68H) … ; 在此处理相等的情况 K1: JC K3 ;因CY=1, 判断出 (R7)<68H, 转K3执行 … K3: … 00:53:27
(2)条件转移指令(8条) 3) 循环转移指令(2条) DJNZ (字节),rel (用于控制循环次数和转移地址) 这是一条字节内容减1并与0比较的指令, 程序每执行一次该指令, 就把字节变量减1, 结果再送回 到字节中, 并判字节内容是否为0, 不为0转移, 否则顺 序执行。 注意: 若字节变量原值为00H, 则指令执行后, 变为0FFH (不影响任何标志), 从而DJNZ循环要执行256次。 循环转移指令共有两条: DJNZ direct, rel DJNZ Rn, rel 00:53:27
3)循环转移指令(2条) 循环转移指令共两条: DJNZ direct, rel DJNZ Rn, rel 指令操作过程如图。 内容先减1,然后再判断是否为0? (rel 一般用符号地址) 循环转移的目标地址为DJNZ之后相邻指令的第一个字 节地址与带符号的相对偏移量相加之和。 用该指令很容易构成循环, 只要给直接地址或工作寄存 器赋不同初值, 就可方便地控制循环次数, 而用不同的 工作单元或寄存器就可派生出很多条循环转移指令。 00:53:27
软件延时就是使程序在运行时消耗时间,是 经常采用的方法,这种方法节约硬件成本, 使用灵活,计时精确; 3)循环转移指令(2条) DJNZ用于软件延时 软件延时就是使程序在运行时消耗时间,是 经常采用的方法,这种方法节约硬件成本, 使用灵活,计时精确; 但是占用了CPU的时间,经常使用在对CPU 的使用效率要求不苛刻的情况下。 00:53:27
3)循环转移指令(2条) DJNZ实现软件延时 (对传统8051单片机) DJNZ指令执行时间为2 个机器周期(24个时钟) , 循环一 次可产生2个机器周期延时。当主频12MHz, 循环次数 为24次时, 下面的程序可产生49us的软件延时循环, 在 P1.0引脚上输出一个50μs的负脉冲。(传统8051单片机) CLR P1.0 ;12T(12个时钟), P1. 70输出变低电平 MOV R2, #18H ;12T, 赋循环初值 HERE: DJNZ R2, HERE ;24T, R2 ← R2-1,不为零继续循环 SETB P1.0 ;12T, P1.70输出高电平 循环延时时间大约为: (12+(24*24))/12MHz=49μs P1.0引脚输出50μs负脉冲: (12+ (12+(24*24))/12MHz=50μs 00:53:27
3)循环转移指令(2条) DJNZ实现软件延时 (对STC15系列单片机) DJNZ指令执行时间为2 4个机器周期时钟, 循环一次可 产生2 4个机器周期时钟延时。当主频12MHz, 循环次数 为24次时, 下面程序可产生49μs的软件延时循环, 在P1.0 引脚上输出一个50μs的负脉冲。(对STC15系列单片机) CLR P1.0 ;3T(3个时钟), P1. 70输出变低电平 MOV R2, #18H ;2T, 赋循环初值 HERE: DJNZ R2, HERE ;4T, R2 ← R2-1,不为零继续循环 SETB P1.0 ;3T, P1. 70输出高电平 8.167μs 8.417μs 循环延时时间大约为: (2+(24*4))/12MHz =8.167μs P1.0引脚输出50μs负脉冲: (3+2+(24*4))/12MHz =8.417μs 00:53:27
3)循环转移指令(2条) DJNZ实现重复执行程序代码 例, 多个单字节数求和: 设数组长度放R0, 数组首地址放 在R1中, 数组和保存在20H单元中, 假设相加结果不大于 256(不考虑加法进位)。编程如下: CLR A ; A清0 SUMC:ADD A, @R1 ; 相加 INC R1 ; 数据地址指针增1 DJNZ R0, SUMC ; 字节数计数器减1, 不为0继续加 MOV 20H, A ; 结果存20H单元 地址 数据 30H 04H 31H 08H 32H 15H 33H 34H 23H … R1=30H→ 00:53:27
§4.8 控制转移类指令(17条) (3条) 1、程序转移指令(12条) 无条件转移 (4条) 条件转移(8条) §4.8 控制转移类指令(17条) 1、程序转移指令(12条) 无条件转移 (4条) 条件转移(8条) 2、子程序调用和返回指令(3+2条) 长调用指令 绝对调用指令 返回指令 中断返回指令 空操作指令NOP (3条) 00:53:27
2、子程序调用和返回指令 子程序的功能 子程序就是用来对一系列指令进行封装,实现模块化、可重用化及抽象化,从而有利于程序的结构化开发,使程序结构更清晰。 合理划分代码结构是软件成功的基本保障。 每种微处理器或者微控制器都有子程序的调用和返 回指令。 对于STC15F2K60S2单片机来说,有两条调用指令: LCALL(长调用)及ACALL(绝对调用)和一条与之配 对的子程序返回指令RET。 00:53:27
2、子程序调用和返回指令 (1)长调用指令 LCALL addr16 ; PC ←PC+3 SP←SP+1 (SP)←PC7~0 PC ←addr16 下条指令地址 断点低8位地址 操作 (保护断点) 断点高8位地址 跳转到调用程序地址 长调用与LJMP一样提供16位地址,可调用64KB范围内所指定的子程序。 例:LCALL STR ;表示调用STR子程序 00:53:27
2、子程序调用和返回指令 (2)绝对调用指令 ACALL addr11 ; PC ←PC+2 SP←SP+1 (SP)←PC7~0 PC10~0 ←addr11 PC15~11不变 下条指令地址 断点低8位地址 操作 断点高8位地址 跳转到调用程序地址 该指令提供11位目标地址,限在2KB地址范围内调用 子程序,由于受2KB的限制,因此,一般程序中使用 LCALL指令代替。 00:53:27
2、子程序调用和返回指令 (3)返回指令 PC15~8←(SP) SP←SP-1 PC7~0←(SP) RET; 操作 调用指令的下条指令地址 (3)返回指令 RET; PC15~8←(SP) SP←SP-1 PC7~0←(SP) 恢复高8位断点地址 操作 恢复低8位断点地址 RET表示子程序结束,要返回主程序,从堆栈中弹出 调用子程序时压入的返回地址, 使程序从调用指令(LCALL或ACALL) 的下面一条相 邻指令处开始继续执行。 00:53:27
2、子程序调用和返回指令 (4)中断返回指令 PC15~8←(SP) SP←SP-1 PC7~0←(SP) RETI; 操作 中断时执行指令的下条指令地址 PC15~8←(SP) SP←SP-1 PC7~0←(SP) 恢复高8位断点地址 RETI; 操作 恢复低8位断点地址 操作还包括: 将相应中断优先级状态触发器清0,将 不可寻址的“优先级生效”触发器清零的功能。通 知中断系统,中断服务程序已执行完毕。 该指令用于中断服务子程序的返回, 其执行过程类似 RET, 但不能由RET替代, 详见与中断有关的章节。 00:53:27
2、子程序调用和返回指令 (5)空操作指令NOP NOP ;PC←PC+1 执行本指令除了PC加1外不作任何操作,而转向下一 条指令去执行。不影响任何寄存器和标志位。 由于是单周期指令,所以时间上只有一个机器周期。 常用于精确延时或时间上的等待。 00:53:27
(5)空操作指令NOP 例如,利用NOP指令产生方波。 LOOP: CLR P2.7 ;P2.7清0输出 NOP ;空操作 NOP SETB P2.7 ;置位P2.7高电平 LJMP LOOP 00:53:27
§4.9 汇编语言程序设计 4.9.1 伪指令 用户将编辑好的汇编语言源程序通过专门的软件(称为 汇编程序)汇编成相应的机器语言程序时,需要有一些 专门的说明性语句。 例如,指定目标程序或数据存放的起始地址、给一些 指定的标号赋值、在内存中予留工作单元、表示源程 序结束等指令 指令并不产生对应CPU操作的机器码,故称为伪指令 (Pseudo-Instruction),也叫做指示性语句;相对应的, 可以产生实质性操作的指令叫做指令性语句。指令性 语句表示了CPU要进行的某种操作。 例, MOV A, #30H, 表示将立即数30H送到寄存器A中。 00:53:27