《单片机原理与应用技术》课件1第2章_第1页
《单片机原理与应用技术》课件1第2章_第2页
《单片机原理与应用技术》课件1第2章_第3页
《单片机原理与应用技术》课件1第2章_第4页
《单片机原理与应用技术》课件1第2章_第5页
已阅读5页,还剩145页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第2章单片机汇编语言编程技术2.1指令格式2.2寻址方式2.3指令系统2.4伪指令2.5几种典型结构的汇编语言程序设计2.6小结习题与思考题2.1指令格式

MCS-51系列单片机汇编语言的每一条语句由4部分组成:

[标号:]助记符[操作数][;注解]格式中用[]围起的是按需要设置的部分,显然,对所有指令而言,助记符是必不可少的。标号:由1~8个字符组成的语句地址符号,必须以字母开头,其余字符可使用字母或数字。标号既可代表本条指令,也可代表本条指令操作码在ROM中存放的第一个存储单元地址。标号必须以冒号“:”结束。助记符:又称操作符,是指令的必不可少部分,它使用接近于人类自然语言的形式帮助人们记住指令的功能,如MOV(传送)、ORL(或逻辑运算)等。操作数:参加操作的数据或数据所在存储单元的地址。操作数允许没有、1个、2个或3个,按指令的操作功能而设置。当有多个操作数时,每个操作数之间用逗号“,”隔开。若有两个操作数,则目的操作数在前,源操作数在后。操作结果存放的存储单元称为目的操作数,操作数的来源称为源操作数。目的操作数与助记符之间用空格隔开。注解:用分号“;”开头,为本条指令的操作功能说明。按照有无操作数划分,指令可分成两大类:无操作数指令和有操作数指令。前一类指令由助记符组成;后一类指令由助记符和操作数组成。常见的指令格式有以下四种:

●助记符

●助记符1个操作数

●助记符目的操作数,源操作数

●助记符第1操作数,第2操作数,第3操作数例如指令MOVA,#2AH,其中“MOV”就是助记符,“A”是目的操作数,“#2AH”是源操作数,该指令表示把立即数2AH送到累加器A中。2.2寻址方式寻找操作数或操作数所在存储单元地址的方式,简称寻址方式。寻址方式越多,指令操作越灵活,操作功能越强。显然,只有“有操作数指令”才存在寻址方式问题。操作数只可能出现在如下几个地方:

(1)在指令中以立即数的形式出现,立即数是存放在程序存储器中的常数,在指令中用“#”引出。

(2)在128BRAM中。

(3)在SFR中。

(4)在片外64KB数据RAM中。

(5)在片内或片外64KB程序ROM中。

(6)在I/O端口中。由此得到相应的单片机寻址方式有三种,分别为:立即寻址、存储器寻址(含I/O端口寻址)和寄存器寻址。2.2.1立即寻址立即数出现在指令中的寻址方式,称为立即寻址。例如,指令MOVA,#2AH的源操作数寻址方式就是立即寻址,因为源操作数#2AH是立即数。2.2.2存储器寻址

1.直接寻址存储单元地址以字节地址形式出现的寻址方式称为直接寻址。对于片内RAM,字节地址范围为00H~FFH;对于ROM和片外RAM,字节地址范围为0000H~FFFFH。例如,指令MOVA,2AH的源操作数寻址方式就是直接寻址。

2.寄存器间接寻址操作数在存储器中,而存储单元的地址由寄存器给出的寻址方式,称为寄存器间接寻址。用于表示存储单元地址的寄存器称为间接寻址寄存器,简称间址寄存器。间接寻址用@后跟随间址寄存器名表示,并不是所有的寄存器都能成为间址寄存器,仅仅只有R0、R1、DPTR、A+PC、A+DPTR才有资格成为间址寄存器。在指令中能够见到的间接寻址形式只有@R0、@R1、@DPTR、@A+PC和@A+DPTR。寄存器间接寻址进一步划分成两类:单一寄存器间接寻址和基址加变址寻址,分别适合于数据RAM和程序ROM的寻址。

1)单一寄存器间接寻址用@R0、@R1、@DPTR指示操作数地址的方式就是单一寄存器间接寻址,这种寻址限于操作数在数据RAM中。例如:

MOV@R0,#30HMOV是数据RAM的送数指令,其中目的操作数所使用的寻址方式就是单一寄存器间接寻址。该指令执行的操作就是把立即数30H送到片内数据RAM的某一单元,该单元的地址由R0给出。又如:

MOVX@R0,#30HMOVX是数据RAM的送数指令,其中目的操作数所使用的寻址方式就是单一寄存器间接寻址。该指令执行的操作就是把立即数30H送到片外数据RAM的某一单元,该单元的地址由P2R0给出,其中P2给出16位地址的高8位,R0给出16位地址的低8位。

2)基址加变址寻址用@A+PC、@A+DPTR指示操作数地址的方式就是基址加变址寻址。这种寻址限于操作数在程序ROM中。操作数地址有16位,由累加器A的内容(8位)加程序计数器PC或数据指针DPTR的内容(16位)形成。例如:

MOVCA,@A+PCMOVC是程序ROM的传送指令,其中源操作数所使用的寻址方式就是基址加变址寻址方式。该指令执行的操作就是先将累加器A的内容(8位)与程序计数器PC(16位)相加,获得程序ROM的单元地址,再将该单元内容送累加器A。假设指令执行前A=06H,PC=2000H,程序ROM2006H单元的内容为5CH,指令执行后,A=5CH。基址加变址寻址仅适用于程序ROM的3条指令,分别如下:

MOVCA,@A+PC MOVCA,@A+DPTR JMP@A+DPTR前两条指令是对程序ROM的读数指令,源操作数使用基址加变址寻址;后一条指令是程序无条件转移的跳转指令,其中的目的操作数使用基址加变址寻址。对于增强型单片机,片内数据RAM有256B,有128B的RAM地址编号为80H~FFH,与SFR地址编号重合,这时需要用不同的寻址方式将它们区别开。使用直接寻址访问80H~FFH的SFR;使用寄存器间接寻址访问80H~FFH的片内RAM。而两种寻址方式都可以访问00H~FFH的片内RAM。

3.位寻址位操作指令中出现的是存储单元某一位的地址,这种寻址方式为位寻址。位地址使用8位二进制数表示,字节地址范围为00H~FFH。位寻址中的位地址和直接寻址中的字节地址,虽然都是8位二进制数00H~FFH,但它们的内容不同:位地址的内容只有1位二进制数,字节地址的内容有8位二进制数。区别它们的唯一方法是看有无“C”出现。试比较:

MOVA,70H;字节操作,源操作数使用直接寻址。

MOVC,70H;位操作,源操作数使用位寻址。

4.相对寻址存储单元的目的地址由PC当前值+字节地址给出,但指令中只出现字节地址,而不出现PC值,这种寻址方式为相对寻址。该寻址方式适用于无条件或条件转移指令。2.2.3寄存器寻址指令中出现的是21个特殊功能寄存器、R0~R7和CY的名字,称为寄存器寻址。操作数就是这些寄存器的内容。例如,指令MOVA,#2AH的目的操作数寻址方式就是寄存器寻址。

【例2-1】设下列每条指令执行前都有A=0CH,(70H)=B8H,R0=30H,(30H)=F1H,PC=3000H,(300CH)=15H,位地址70H的内容为1,判断每条指令源操作数的寻址方式。

(1) MOVA,#70H源操作数为立即寻址,#70为立即数,指令功能为将立即数70H送入A中,执行结果为A=70H。本条指令的目的操作数使用寄存器寻址,是21个SFR中的一个出现在指令中。

(2) MOVA,70H

源操作数为直接寻址,70H为字节地址。指令功能是将地址70H单元的内容送入A中,执行结果为A=B8H。

(3) MOVA,@R0

源操作数为单一寄存器间接寻址。指令功能为(30H)→A,执行结果为A=F1H。

(4) MOVA,R0

源操作数为寄存器寻址,指令功能为R0→A,执行结果为A=30H。

(5) MOVCA,@A+PC

源操作数为基址加变址寻址,指令功能为(A+PC)→A,执行结果为A=15H。本条指令源操作数在ROM中。

(6) MOVC,70H源操作数为位寻址,这是一条位操作指令,指令中“C”表示进位位CY。执行结果为C=1。

(7) SJMPA2H本条指令没有源操作数,无源操作数的寻址;仅有目的操作数,目的操作数的寻址方式为相对寻址。转移目的地址=PC当前值+指令中的字节地址 =本条指令的地址(PC值)+2+指令中的字节地址 =3000+2+A2H

=30A4H本条指令后,程序将执行30A4H单元的内容。单片机寻址方式归结于表2-1中。2.3指令系统

MCS-51系列单片机的指令共有111条,按操作类型划分共分成5大类:

(1)数据传送类指令共29条,分为片内RAM与片外RAM、程序ROM的数据传送、堆栈操作及交换指令。

(2)算术运算类指令共24条,分为加、带进位加、减、乘、除、加1、减1、十进制调整指令。

(3)逻辑运算类指令共24条,分为与、或、异或、移位指令。

(4)位操作指令17条,分为位传送、位与、位或、位求反、位转移指令。

(5)控制转移指令17条,分为无条件转移、条件转移、调用指令。按字节数划分,111条指令可分为单字节指令49条,双字节指令45条,三字节指令17条。按功能划分,111条指令共实现33种操作功能,使用42个助记符号。按执行时间划分,在111条指令中有64条执行时间为12个时钟周期,45条指令需24个时钟周期,2条指令(乘、除)需48个时钟周期。以晶振频率12MHz作时钟脉冲计算,三类指令的执行时间分别为1μs、2μs和4μs。按照上面的分析,可以得出单片机指令系统有如下三个特点:

(1)指令执行速度较快,指令执行时间是1~4μs,长于PC机指令的执行时间。

(2)指令字节数短,仅1~3字节,放入ROM中占存储单元数少,而PC机指令字节长(以8086/8088为例,有1~7字节)。

(3)位指令操作丰富,给微控制带来极大方便,而PC机无位指令。下面介绍的指令中有一些常用符号,含义如下:

Rn:当前寄存器组的8个通用寄存器R0~R7。

Ri:具有间接寻址功能的寄存器R0、R1。

dir:片内256BRAM的字节地址,取值范围为00H~FFH,如20H表示地址。

(dir):存储单元的内容,如(20H)=94H,表示地址为20H单元中的内容是94H。

#data8:8位立即数。

#data16:16位立即数。

@:间接寻址寄存器的引导标志。

dest_lable:目标语句的标号。

addr11:11位地址。

addr16:16位地址。

bit:128BRAM和SFR中的位地址。

rel:8位补码偏移量,取值范围为-128~+127(00H~FFH)。

/:取反。

SFR名:SFR中存放的内容,如A=60H表示A中存放的内容为60H。

dest:目的操作数。

source:源操作数。2.3.1数据传送指令

29条数据传送指令需要用到8种不同含义的助记符:MOV、MOVX、MOVC、PUSH、POP、XCH、XCHD、SWAP。每一个助记符实现一种操作功能,一共能完成8种操作功能。按操作类型划分,共分成5类,如表2-2所示。

1.片内数据RAM传送指令格式:MOVdest,source功能:source→dest。执行结果为源操作数送目的操作数,源操作数不变。本指令包括8位数传送和16位数传送两种类型,指令格式共有16种。

1) 8位数传送传送示意图如图2-1所示。目的操作数和源操作数允许是片内128BRAM任一单元以及SFR,此外,源操作数还允许是8位立即数。图2-18位MOV指令

2) 16位数传送传送示意图如图2-2所示。16位数传送指令仅一条,即MOVDPTR,#data16。图2-216位MOV指令

【例2-2】指令“MOVDPTR,#4050H”的操作功能为4050H→DPTR,结果为DPTR=4050H。它相当于两条8位数MOV传送指令:

MOVDPL,#50H;50H→DPL MOVDPH,#40H;40H→DPH将累加器A为目的操作数的指令单独列出,是因为这一类指令执行时间短,执行速度快。例如:

MOVA,R0的执行时间是12个时钟周期,而用字节地址表示的指令(A的字节地址是E0H) MOVE0H,R0执行时间却需要24个时钟周期。但两条指令的执行结果完全相同。此外,MOVA,R0是单字节指令,机器码只占ROM一个单元;MOVE0H,R0是双字节指令,机器码占ROM两个单元。因此在选用指令的时候要尽量选用有A的指令。

【例2-3】将立即数40H送至A,将A的内容送至寄存器R3,将R3的内容送至50H单元,将50H单元内容送至60H单元,相应各条指令如下:

MOVA,#40H ;40H→A MOVR3,A ;A→R3 MOV50H,R3 ;R3→(50H) MOV60H,50H ;(50H)→(60H)

【例2-4】设A=80H,70H单元的内容为F0H,记为(70H)=F0H。

MOVA,#70H;立即数70H→A,指令执行结果A=70H MOVA,70H

;70H单元的内容送A,执行结果A=(70H)=F0H

2.片外数据RAM与A之间的传送指令片外数据RAM与A之间的传送指令操作码、字节数、时钟周期如下:

指令格式 操作码 字节数 时钟周期

MOVXA,@Ri E2,E3 1 12 MOVXA,@DPTR E0 1 24 MOVX@Ri,A F2,F3 1 24 MOVX@DPTR,A F0 1 24指令助记符MOVX的示意图如图2-3所示。图2-3MOVX指令

1)从片外RAM传送到A格式:MOVXA,@Ri MOVXA,@DPTR功能:片外64KBRAM中某一存储单元内容送入A。该单元的地址使用两种方法出现在指令中。第一种使用@Ri寻址,片外64KBRAM的16位地址由P2Ri给出,P2中存放着高8位地址,不出现在指令中,指令格式中仅出现存放低8位地址的Ri(i=0,1);第二种使用@DPTR寻址,DPTR内容就是16位地址。

2)从A传送到片外RAM格式:MOVX@Ri,A MOVX@DPTR,A功能:A内容送入片外RAM某一单元,该单元地址在P2Ri或DPTR中。

【例2-5】编程将累加器A中的内容输出到片外数据RAM7086H单元。

解:程序一:

MOVP2,#70H MOVR0,#86H ;建立片外数据RAM地址指针

MOV@R0,A ;输出数据程序二:

MOVDPTR,#7086H ;建立地址指针

MOV@DPTR,A ;输出数据

3.从程序ROM向A送数的指令格式:MOVCA,@A+PC ;(A+PC)→A MOVCA,@A+DPTR ;(A+DPTR)→A指令助记符MOVC的示意图如图2-4所示。从ROM向A送数指令的操作码、字节数、时钟周期如下:

指令格式 操作码 字节数 时钟周期

MOVCA,@A+DPTR 93 1 24 MOVCA,@A+PC 83 1 24图2-4MOVC指令

【例2-6】查表求平方程序。

MOVA,#03H ;A=3 MOVCA,@A+PC

;执行完本指令PC=RETU,A+PC=3+RETU RETU:RET ;返回指令,一字节

TABLE:DB01H04H09H10H19H

;DB建立了一个平方表依次存放着12、22、32、42、52执行MOVC后,A﹦09H。

4.堆栈操作指令格式:

PUSHdir ;SP+1→SP,(dir)→(SP) POPdir ;(SP)→(dir),SP-1→SP功能:PUSH指令是入栈指令,入栈又称推入堆栈或进入堆栈。指令操作分为两步:首先SP自动加1,接着是存储单元的内容进入SP所指的单元,这样,SP仍然指向栈顶。POP指令是出栈指令,又称弹出,分两步完成:SP所指单元内容送到存储单元(该单元地址由dir给出),随后SP自动减1,依旧指向栈顶。操作特点:单片机堆栈操作为字节操作,入出栈均为1字节。单片机初始化后SP=07H,入栈的数据从08H单元开始存放,由于08H恰好在工作寄存器区(00H~1FH)内,因此在程序中最好用MOV指令重新给SP赋值建立堆栈区,堆栈建立时不宜太深,通常设置在从20H开始的片内RAM中。堆栈操作指令的操作码、字节数、时钟周期如下: 指令格式 操作码 字节数 时钟周期

PUSHdir C0dir 2 24 POPdir D0dir 2 24

【例2-7】利用堆栈操作将3AH单元和3BH单元内容互换。

解: MOV SP,#20H ;建立堆栈

PUSH 3AH ;3AH单元内容入栈,进入21H单元

PUSH 3BH ;(3BH)→(22H) POP 3AH ;3BH单元内容出栈,弹出到3AH单元

POP 3BH ;3AH单元内容出栈,弹出到3BH单元

SJMP $ ;程序段结束

SJMP是相对转移指令,$表示本条指令首地址,SJMP$的功能是循环执行本条转移指令实现动态停机。MCS-51系列单片机无停机指令,如果不用本条指令停机,单片机将依次执行后面的随机代码而陷入死机。有关SJMP指令的详细说明见2.3.5节。

5.交换指令交换指令有两种,一种是8位数交换,一种是4位数交换。前一种是A与256BRAM单元内容互换;后一种分成两类:第一类是A与256BRAM单元内容低半字节交换,第二类是A的高低4位交换。格式:

XCH A,Rn ;A←→Rn XCH A,@Ri ;A←→(Ri) XCH A,dir ;A←→(dir) XCHD A,@Ri ;A0~3←→(Ri)0~3 SWAP A, ;A0~3←→A4~7

【例2-8】

编程将60H单元内容与70H单元内容互换。

解:MOVA,60H ;(60H)→A XCHA,70H ;(A)←→(70H),A中为70H单元内容

MOV60H,A ;(70H)→(60H) SJMP$ ;程序段结束交换指令执行示意图如图2-5和图2-6所示。图2-58位交换指令图2-64位交换指令交换指令的操作码、字节数、时钟周期如下:指令格式 操作码 字节数 时钟周期XCHA,Rn C8~CF 1 12XCHA,@Ri C6,C7 1 12XCHA,dir C5dir 2 12XCHDA,@Ri D6,D7 1 12SWAPA C4 1 122.3.2算术运算指令算术运算指令含有8类共24条,使用8种助记符完成8种不同的算术操作,指令一览表如表2-3所示,其中加法指令和减法指令有一个共同的特点,就是目的操作数都是累加器A。

1. ADD指令

ADD指令有4条,功能是不带进位位相加,只有两个加数,相加以后,和放入A中,第3位和第7位的进位分别放在程序状态字PSW的AC位和CY位中。当两个有符号数相加时,加数与相加结果一律为补码,还会对溢出标志OV产生影响,有溢出时使OV=1,否则OV=0。

【例2-9】设A=69H,R3=44H,执行ADDA,R3。

A01101001

+) R301000100 010101101→A两正数相加得负数,证明产生溢出,所以OV=1,CY=0,AC=0,A=0ADH。

2. ADDC指令

ADDC指令有4条,功能是带进位位加法,有3个加数:目的操作数、源操作数和CY位。相加的结果和放入A中,半进位和进位放入AC和CY标志位中,对溢出位的影响同于ADD指令。

【例2-10】

设A=69H,R3=44H,CY=1,执行ADDCA,R3。

A  01101001   R3 01000100

+)CY1

   0 10101110→A执行结果:

A=0AEH,OV=1,CY=0,AC=0。

【例2-11】

编程计算1234H+5678H,和放在30H和31H中。

解:CLR C ;CY清零

MOV A,#34H ADD A,#78H ;低字节相加

MOV 30H,A ;送低字节之和

MOV A,#12H ADDCA,#56H ;高字节带CY位相加

MOV 31H,A ;送高字节之和

SJMP $ 执行结果:

1234H+5678H=68ACH,(30H)=ACH,(31H)=68H,

CY=0,OV=0,AC=0

【例2-12】

编程计算R5+R6+CY,结果放入R7。若程序从ROM2000H单元开始存放,画出存储图。设时钟频率为12MHz,问该程序执行完需要多长时间?

解:指令 操作码 字节数 时钟周期TMOV A,R5

EC

1

12ADDC A,R6

3E

1

12MOV R7,A

FF

1

12占ROM3个单元,存储图如图2-7所示。程序执行完需时36T=36×1/12MHz=3μs。图2-7例2-12用图

3. SUBB指令

SUBB指令有4条,功能是带进位位的减法指令。被减数是目的操作数A。有两个减数,一个是片内RAM单元的内容,一个是进位标志CY。相减的结果送入A和CY,其中A中存放差,CY中存放借位位。够减时借位位为0,不够减时为1。

【例2-13】

设A=46H,编程计算A-68H。解:CLRC ;没有不带进位位的减法指令,先使CY=0 SUBBA,#68H

SJMP$ 执行结果为A=0DEH,CY=1(被减数有借位),AC=1(D3向D4有借位),OV=0(无溢出)。若是两个无符号数相减,成为146H-68H,结果正确。若是两个有符号数相减,因OV=0,结果是-34的补码DEH,也正确。

4. MUL指令

MUL指令(1条)的功能是A、B寄存器中的内容相乘,乘积高8位放入B中,乘积低8位放入A中。指令执行结果将对CY清零,并影响溢出标志位OV以及奇偶标志位P。其中积大于255时OV=1,否则为0;A中二进制数位“1”的个数为偶数时,P=1,否则P为0。

【例2-14】A=A0H,B=50H,执行MULAB后,A=00H,B=32H,CY=0,OV=1,P=0。

5. DIV指令

DIV指令(1条)的功能是A除以B,A中数据是被除数,B中数据是除数,相除结果的商数放入A,余数放入B。指令执行结果将使CY清零,并影响溢出标志OV及奇偶标志P。当除数为0时OV=1,除数不为0时OV=0。A中“1”的个数为偶数时,P=1,否则P为0。

【例2-15】

A=13H,B=05H,执行DIVAB后,A=03H,B=03H,CY=0,OV=0,P=1。

6.加1指令加1指令有5条,功能是源操作数内容自动加1。例如设A=03H,执行INCA后,A=04H。

7.减1指令减1指令有4条,功能是源操作数内容自动减1。例如设A=03H,执行DECA后,A=02H。加1指令与减1指令中,仅有INCA和DECA执行后对奇偶标志P有影响(对P的影响同于乘法指令)。其它指令不影响标志位。

8. DA指令

DA指令(1条)是十进制调整指令,它位于ADD指令或ADDC指令之后,将二进制数相加改变成十进制数相加。

【例2-16】

写出下列程序的每条指令执行结果。

MOVA,#48H ;A=48H ADD A,#23H ;48H+23H=6BH,即A=6BH DA A

;A=48+23=81H,表示结果为十进制数81 SJMP  $ ;动态停机2.3.3逻辑运算指令逻辑运算指令使用9种助记符实现9个不同的逻辑操作,分别是:

ANL(与)、ORL(或)、XRL(异或)、RL(循环左移)、RR(循环右移)、RLC(带CY位循环左移)、RRC(带CY位循环右移)、CPL(求反)、CLR(清零)。逻辑运算指令包括4类24条,分别是:①与运算指令ANL6条;②或运算指令ORL6条;③异或运算指令XRL6条;④ A专用指令6条,包括将A清零(结果A=0)、将A求反(结果→A)和将A循环移位。其中A的循环移位指令见图2-8。图2-8A的循环移位指令目的操作数为A的指令影响奇偶标志P。带CY位的指令影响进位标志CY。其它的指令不影响PSW各位。指令一览表见表2-4。

【例2-17】

A=0F2H,R1=30H,(30H)=1AH。执行ANLA,@R1后,A=12H;执行ANLA,R1后,A=30H;执行RLA后,A=E5H;执行CPLA后,A=0DH。

【例2-18】

写出每条都能使A=00H的指令。

MOVA,#00H

ANLA,#00H

XRLA,A

CLRA

【例2-19】

指令SUBBA,A能否使累加器A为0?答:不行,因为CY未知。2.3.4位操作指令位操作指令共有7类17条,使用11种助记符实现11个功能。指令格式如表2-5所示。格式中的C指进位标志CY,在位操作指令中,C起到位累加器的作用。而bit是位存储器地址,包括片内RAM位寻址空间的128位(位地址00H~7FH)和SFR中的可寻址位128位(位地址80H~FFH)。指令格式中的位地址“bit”的书写形式有如下几种:

(1)使用直接地址00H~FFH。

(2)使用SFR的第几位,如PSW.5,P3.0。

(3)使用字节地址的第几位,如21H.2指字节地址21H单元的第2位,该位地址为0AH。

(4)直接用位名称表示,如RS1、RS0、EA等。

(5)使用BIT伪指令定义,如伪指令VOLBITC3H,含义为将位名(位的名字)VOL定义成C3H,若位名VOL在以后的指令中出现,就表示位地址为C3H。伪指令的进一步叙述见2.4节。

【例2-20】

把位地址20H的内容传送到C。

MOVC,20H

【例2-21】把P1.0状态传送到RS1。

MOVC,P1.0 MOVRS1,C

【例2-22】X、Y、Z均为2位二进制数,且Z=XY,已知X、Y,编程求Z。

解:设X=X1X0,Y=Y1Y0,Z=Z1Z0,异或运算为位运算,只需两位分别进行。程序编制可按照异或运算规则实现:X00=X0,X01=,选用Y0作转移条件。设X1X0放在21H、20H位存储器中,Y1Y0放在23H、22H位存储器中,Z1Z0放在25H、24H位存储器中。 X0BIT20H ;使用伪指令BIT定义位地址

X1BIT21H Y0BIT22H Y1BIT23H Z0BIT24H Z1BIT25H MOV C,X0 ;X0存入C JNB Y0,X0ZERO ;Y0=0转Z0=X0=C CPL C ;求反,C中为 X0ZERO:MOV Z0,C ;送结果

MOV C,X1 JNB Y1,X1ZERO CPL C X1ZERO:MOV Z1,C SJMP $

【例2-23】检测P1.0,若P1.0=0,则将P1.1送入C累加器;若P1.0=1,则从P1.4输出1。

JNB P1.0,TEXTP11 ;P1.0=0转至TEXTP11 SETB P1.4 ;P1.0=1时从P1.4输出1

TEXTP11:MOV C,P1.1 ;将P1.1的内容送入C2.3.5控制转移指令控制转移指令包含控制、转移、调用共3类17条指令,使用13种助记符实现13种功能。其中转移类指令又分为无条件转移和条件转移两种,调用类指令分为无条件调用和返回两种。指令格式如表2-6所示。

1. NOP指令本指令为空操作,什么事也不做,用于产生一个机器周期的延时或修改程序时作填充用,便于添加或删去指令。

2.无条件转移指令无条件转移指令可分为直接转移和间接转移两种。直接转移的特征是目标地址或目标语句的标号直接出现在指令格式中。直接转移指令按目标地址与转移指令地址距离的远近分成3类:近距离转移(SJMP)、短距离转移(AJMP)和长距离转移(LJMP)。用A+DPTR间接指出转移目标属于间接转移,间接转移指令的助记符仅有JMP一种。

1) SJMP指令格式:SJMPdest_lable功能:PC首地址+2+rel→PC目标地址,其中箭头“→”左边的“PC首地址”是本条指令所占存储单元的首地址,rel是转移的相对偏移量,大小为1字节补码(-128~+127),箭头右边的“PC目标地址”是转移后的目标指令所占存储单元的地址。目标地址限于在本条指令地址值上下-126~+129处,转移范围如图2-9所示。人工计算rel的过程称为人工汇编;由计算机编译程序计算并填入rel的过程称为机器汇编。图2-9SJMP的转移范围

【例2-24】

计算HERE:SJMPHERE的偏移量rel,写出机器码,叙述其功能。

解:按照SJMP指令的功能:

PC首地址+2+rel=PC目标地址所以

rel=PC目标地址-PC首地址-2

=HERE-HERE-2

=-2取补码,rel=[-2]补=FEH。本条指令机器码为80FEH。本条指令还可以用SJMP$取代,指令中既用$代表“PC目标地址”,又用$代表“PC首地址”,机器码仍然为80FEH。这是一条使程序原地踏步的指令,在仿真器上调试程序时,常用SJMP$结束程序段。

【例2-25】设SJMP的首地址为3210H,求机器码中的rel。①目标地址324DH;②目标地址3206H。

解:① rel=[324DH-3210H-2]补=3BH② rel=[3206H-3210H-2]补=[-0CH]补=F4H

2) AJMP指令格式:AJMPdest_lable功能:PC+2→PC,addr11→PC10~PC0。用a10a9…a1a0表示Addr11的11位二进制数,本条指令执行结果就是这11位二进制数送入PC的第10位~第0位。指令机器码是a10a9a800001a7~a0,为2字节指令。指令特征:① addr11是目标指令所在存储单元地址的低11位a10~a0,因此目标地址转移最大范围为211=2KB,如图2-10所示。如果转移目标超出了这个范围,就不能使用AJMP。② addr11是转移目标的部分地址值,通常不在程序中出现,程序中书写本条指令只需在AJMP后写上目标语句的标号。图2-10AJMP的转移范围

【例2-26】

人工汇编将机器码填入下列程序的空格内。地址(H) 机器码(H) 程序段①201A — — MOVA,#0AH②201C 80 — SJMPX③201E 66H XRLA,@R0④201F F4H X: CPLA⑤2020 — — AJMPY⑥2032 23H Y: RLA⑦2033 80 — SJMP$第①句查MOV指令,机器码为74

0AH。第②句rel=201FH-201CH-2=1H,机器码填入8001H。第⑤句机器码为a10a9a800001a7~a0,先查找标号为Y的语句,首地址

2032H=0010000000110010B它的a10~a0=00000110010B,所以机器码是0000000100110010B=0132H,填入01

32H。第⑦句SJMP$的机器码为80FEH。

3) LJMP指令格式:LJMPdest_lable功能:PC+3→PC,addr16→PC,本条指令是3字节指令,机器码占程序ROM中的3个单元。由于目标地址有16位出现在机器码中,因此转移范围为216B=64KB,如图2-11所示。LJMP指令又叫长距离转移指令。本条指令在程序中出现时,LJMP后面只需写出转移目标的标号,不必写出转移目标的地址。图2-11LJMP指令

4)间接转移指令JMP格式:JMP@A+DPTR功能:A+DPTR→PC

【例2-27】设DPTR=3000H,在下列情况下执行JMP@A+DPTR。①如果A=10H,执行后,PC=3010H,程序转移到3010H单元去执行。②如果A=20H,执行后,PC=3020H,程序转移到3020H单元去执行。③如果A=30H,执行后,PC=3030H,程序转移到3030H单元去执行。

【例2-28】

分析下列程序执行过程:

MOV DPTR,#TABLE JMP @A+DPTRTABLE: AJMP TUBLE0 AJMP TUBLE1 AJMP TUBLE2

AJMP TUBLEn当A=00H时,程序转去执行TUBLE0;当A=02H时,程序转去执行TUBLE1;当A=2nH时,程序转去执行TUBLEn这是一个多分支转移程序,执行哪一分支由A取值决定。由于AJMP是2字节指令,因而要求A取偶数。分支过程如图2-12所示。图2-12分支过程用图

3.条件转移指令

1)累加器A条件转移

●JZ指令格式:JZdest_lable功能:A=0时转至执行dest_lable引出的指令,A≠0时执行下一条指令。

●JNZ指令格式:JNZdest_lable功能:A≠0时转至执行dest_lable引出的指令,A=0时执行下一条指令。说明:两条指令rel的计算方法与SJMP指令相同。

2) 减1非零条件转移(DJNZ)指令格式:DJNZRn,dest_lable功能:Rn-1→Rn,Rn≠0时转至执行dest_lable引出的指令;

Rn=0时执行下一条指令;

rel计算同于SJMP指令。格式:DJNZdir,dest_lable功能:(dir)-1→(dir),(dir)≠0时转至执行dest_lable引出的指令;

(dir)=0时执行下一条指令;

rel=PC目标地址-PC源地址-3,本指令为3字节。

【例2-29】

从P1.0输出频率为5Hz的方波,晶振频率为12MHz。START: CLRP1.0DELAY: MOV20H,#C8H ;(20H)=200LOOP:

MOV21H,#FAH ;(21H)=250 DJNZ21H,$ ;本条指令执行时间为2μs DJNZ20H,LOOP ;高低电平各延时100μs CPL P1.0 AJMPDELAY

【例2-30】编程完成Y=X1+X2+…+Xn,设n=20,设Xi(i=1,2,3,…,n)依次存放在片内RAM从40H开始的连续单元中,Y放入50H和51H两个单元。解:MOV R0,#20 ;数据个数→R0MOV 50H,#00 MOV 51H,#00 MOV R1,#40H ;数据区首址→R1LOOP: MOV A,50H ADD A,@R1 ;相加MOV 50H,A ;存和的低字节CLR A ADDC A,51H MOV 51H,A ;存和的高字节INC R1 ;修改地址指针DJNZ R0,LOOP ;未加完继续取数相加SJMP $

3)比较不相等转移指令比较不相等转移指令有4条,格式和功能如下:比较不相等转移指令的特征如下:①每条指令都有3个操作数,各操作数均为无符号数。②指令执行过程是:第一操作数与第二操作数进行比较,比较结果决定了程序下一步的走向。如果前两个操作数不相等,则转移执行由第3操作数表示的目标语句;如果相等,则按顺序执行紧随其后的下一条指令。③第一操作数与第二操作数比较后不送结果,它们各自的内容不变。④第3操作数是转移目标,转移范围在离源指令256B以内,计算公式为:rel=PC目标地址-PC源地址-3⑤每条指令均为3字节指令,在程序ROM中存放时占3个存储单元。⑥每条指令执行后对进位标志产生影响。如果第一操作数≥第二操作数,无借位,CY=0;如果第一操作数<第二操作数,有借位,CY=1。

【例2-31】人工汇编计算rel并填入机器码。第1条指令是2字节指令,因此第2条指令存放的ROM单元地址是01

02。又CJNE是3字节指令,P0的字节地址为80H,rel=0120H-0102H-3=1DH,故机器码填入B5

80

1D。

【例2-32】利用CJNE指令影响CY位用于判断两个无符号数的大小。大、小数分别存入GREAT和LESS单元。

4.调用指令调用指令全称是子程序调用指令,分成无条件调用和返回指令两类。按照被调用子程序与调用指令之间的距离长短,无条件调用分成短调用和长调用两种。ACALL指令是短调用指令,该指令所调用的子程序入口地址在ACALL指令2KB范围内,超出这个范围无法调用。LCALL指令是长调用指令,它可调用64KB范围内程序ROM中任一个子程序,执行后不影响标志位。返回指令有两条,一条是RET,与ACALL或LCALL指令配合使用,子程序执行完毕,必须依靠RET返回主程序,继续执行调用指令的下一条指令。返回过程由RET指令实施,因此,RET返回指令的位置必然位于子程序的最后,即子程序的最后一条指令必定是RET。另一条返回指令是RETI,专用于执行中断服务程序后返回主程序,所以中断服务程序的最后一条指令必定是RETI。

1)无条件调用指令

●ACALL指令格式:ACALLdest_lable ;短调子程序功能:调用处断点被自动推入堆栈,PC+2→PC,addr11→PC10~0,其中addr11是子程序入口地址的低11位a10~a0。本指令的机器码是a10a9a810001a7~a0,确定方法与AJMP指令相同。本条指令使用时,格式中的addr11不出现在程序中,出现在助记符ACALL后面的是目标语句标号“dest_lable”,它是被调子程序第一条语句的标号或子程序名。本条指令是2字节指令,不影响PSW各位。

●LCALL指令格式:LCALLdest_lable ;长调子程序功能:在64KB程序ROM的全范围内调用子程序,addr16是子程序入口地址的a15~a0位,不出现在程序中,程序中出现在LCALL后面的目标语句标号“dest_lable”是子程序第一条语句的标号或子程序名。本指令是3字节指令,操作码为12addr16。本条指令不影响PSW各位。

2)返回指令格式:RET ;从被调用子程序返回,机器码22H   RETI ;从中断服务程序返回,机器码32H2.4伪指令为汇编程序提供汇编说明的指令叫做伪指令。伪指令无机器代码,不能被执行。一个完整的汇编程序仅有可执行指令是不完善的,必须要有伪指令才能使程序完整。汇编过程离不开伪指令提供的信息。汇编程序中用到的伪指令如表2-7所示。这些伪指令中,有7条是常用的,现介绍如下。

1.程序起始地址伪指令格式:ORG16位地址功能:ORG后面的16位地址就是源程序第1条指令的存放地址,位于程序ROM中。

【例2-33】     ORG0120HSTART:MOVA,#80H

源程序从ROM0120H开始存放,START标号地址就是0120H。

2.程序结束伪指令格式:END或END标号功能:表示汇编结束,位于源程序结尾处。子程序后面的END不用加标号;主程序后面的END需要加标号,该标号只能是ORG后面执行指令的标号,即主程序第一条执行指令的标号或符号地址。

【例2-34】主程序中END的位置。

ORG0120HSTART:

MOVA,#80HSJMP$;本指令是执行指令,用于动态停机

ENDSTART

;本指令是伪指令,不执行,表示汇编到此结束

3.字节定义伪指令格式:标号:DB字节数据、字符或表达式功能:在ROM中开辟数据存储区,以字节为单位依次存放着DB后面的数据。这些数据如果是字符(必须用单引号括起),将以ASCII码形式出现;如果是表达式,则存放着表达式的值。数据区的起始地址可以用标号代替。

【例2-35】程序如下:伪指令YYY:DB01H,04H,09H,'A'就是从0124H单元开始创建一个数据区,依次存放的内容是(0124H)=01H,(0125H)=04H,(0126H)=09H,(0127H)=41H,其中41H是字符A的ASCII码,这个数据区的首址0124H可以使用标号YYY代替。

4.字定义伪指令格式:标号:DW字数据、字符或表达式功能:在程序ROM中开辟以字为单位存放的数据存储区,一个字占两个单元,依次存放。

【例2-36】

伪指令

ABC:DWABCDH,EFH,'AB'要求汇编在程序ROM中从ABC单元开始创建一个数据区,以字为单位存放数据,从ABC单元依次存放ABH、CDH、00H、EFH、41H、42H。

5.存储区定义伪指令格式:标号:DS数值功能:从标号地址开始预留几个字节的存储单元,供程序备用。DS后面的数值就是预留的个数。该指令中也可以不要标号。

【例2-37】ORG300AH DS5

;从300AH单元开始,空出5个存储单元给程序使用

6.符号定义伪指令格式:符号EQU数值或数值表达式功能:汇编识别结果,把数值或数值表达式的值赋给符号,在下面的程序中若出现符号,它的大小就是所赋值。

【例2-38】

XEQU30H ;X=30H  MOVA,X ;结果A=30H

7.位符号定义伪指令格式:符号BIT位地址功能:将位地址赋给符号,该符号只要出现就代表位操作地址。

【例2-39】BINKOUBITP1.0

;将位地址P1.0赋给符号BINKOU CLR  BINKOU ;P1.0清零2.5几种典型结构的汇编语言程序设计汇编语言程序的基本结构有3种:顺序结构、分支结构和循环结构。2.5.1顺序结构程序按操作顺序依次排列指令的程序为顺序结构程序。程序一旦执行,就从第一条指令开始依次执行到最后一条指令结束。

【例2-40】查表求Y=X2+1,X为0~9的整数。

解:设变量X存放在40H单元中,Y值存放在41H单元中。

【例2-41】将片内数据RAM21H和20H中的16位数求反后送回原单元。2.5.2分支结构程序程序在执行过程中,要根据测试条件决定程序的走向,这种程序称为分支结构程序。当程序从一条支路往下继续执行时,其它分支支路上的指令不再被执行。分支程序中必须要有控制转移类指令,测试结果不同,程序的走向不同。

【例2-42】编程实现:

Y=设X以补码形式位于片内数据RAM20H单元,Y值存放在22H、21H单元。

解:先取出X进行是否为0判断,如果不是零,再进行符号位正负判断,每次判断后按题目要求送结果。流程图如图2-13所示。图2-13分支程序由此编制的程序如下:

ORG 0100H MOV 22H,#00H

MOV 21H,#00H CLR C MOV A,20H JZ ZERO JB ACC.7,MINUS

;A为负数,转MINUS MOV B,A

MUL AB

;得X2 MOV 22H,B ;送结果X2→Y MOV 21H,A SJMP $ ZERO:MOV 22H,#00H

MOV 21H,#FFH ;送结果FFH→Y

SJMP $ MINUS: ADD A,#01H

MOV 22H.0,C MOV 21H,A

SJMP $ END 多路分支程序的特点是根据不同输入条件或运算结果,转去执行不同的处理程序。多路分支程序通常使用间接转移指令JMP@A+DPTR实现。具体操作可以通过查转移地址表或查转移指令表完成。使用转移地址表时,应事先将转移地址排成表格驻进存储器,表格的内容依次作为转移目标的地址。使用转移指令表时,同样需事先将不同程序的转移指令列成表格,查表时查到哪个程序的转移指令,就执行哪个程序。

【例2-43】

查转移地址表的程序。设需要转移的目标程序入口地址有n个,编号为DEST0~DESTn-1,每个地址占ROM两个单元,依次排放在从TAB开始的单元中。现在要根据片内RAM20H单元的内容决定转入哪一个目标程序,由此编制的程序如下:

MOV A,20H

;取数

ADD A,A

;A+A→A MOV DPTR,#TAB ;置地址指针

MOVCA,@A+DPTR ;取某一地址高字节

MOV 21H,A

;高字节暂存 MOV A,20H

ADD A,A INC DPTR MOVCA,@A+DPTR ;取低字节

MOV DPH,B MOV DPL,A

;DPTR是TAB中地址

MOV A,#0

;清零

JMP @A+DPTR

;间接转移

SJMP $

TAB:DW DEST0,DEST1,…DESTn-1 END

【例2-44】查转移指令表的程序。设i=0,1。设单片机系统16个键对应的键值00H~0FH存放在工作寄存器R0中,16个键的处理程序入口地址分别为PR0~PR15。在程序ROM中建立一张转移指令表,每条无条件转移指令占3个存储单元,如果用LJMPPRi,机器码将是02PRiHPRiL,如图2-14所示。图2-14转移指令由此编制的程序如下:

ORG 0100H ;取键值

MOV A,R0 ;每条LJMP指令占3个单元

ADD A,R0 ADD A,R0 ;A×3→A MOV DPTR,#TAB ;置地址指针

JMP @A+DPTR ;散转TAB:LJMP PR0 LJMP PR1

LJMP PR15 SJMP $ END 2.5.3循环结构程序有一部分指令需要重复执行的程序,称为循环程序。循环程序的优点是程序简练,且占用较少的程序存储空间,设计程序的时间大为缩短,但程序执行的时间不会减少。设计循环程序的主要工作是确定循环体(重复执行的那部分指令)和设置循环条件。分析一个循环程序,一般由4个部分组成:

(1)初始化部分,这是为循环所做的准备,如设置循环次数,设置地址指针等。

(2)循环体部分,这是为了解决题目要求而设计的重复执行指令。

(3)控制循环修改部分,这是为了下一次执行循环体所做的准备,例如循环次数减1,地址指针加1等。

(4)循环判断部分,用于判断是进行循环还是退出循环。循环程序在安排上既可以先循环后判断,也可以先判断后循环。循环结构允许嵌套,在多重循环中大循环内套小循环,但内、外循环不允许交叉,也不允许从外循环跳入内循环中。进入循环体只能从循环体的第一条指令进入,离开循环体既可以从循环体的最后一条指令退出,也可以从循环体中间跳出,显然只需在循环体内设置一条条件转移指令便可跳出。

【例2-45】

延时程序。延时与晶振频率和循环次数有关,设单片机晶振频率为12MHz,一个机器周期为1μs。

(1)使用单循环延时1ms程序。循环体延时计算后两条指令延时4μs,循环250次,再加上第1条指令延时1μs,总共延时1.001ms。

(2)使用多循环延时200ms程序。

MOV R1,#200 ;循环200次DELAY200:MOV R0,#FAH ;R0=250为循环次数DELAY250:MOV R7,70H ;延时2μs DJNZ R0,DELAY250 DJNZ R1,DELAY200

;延时1ms的程序重复200次由于R1最大值为255,因此要想延时超过255ms,需增加循环次数。

【例2-46】排序程序。设片内RAM20H单元开始放有50个无符号字节数,要求将其按从小到大的顺序重新排列,排好后依旧放入这些单元中。排序需要两重循环。内循环负责寻找最小值,两个两个比较,每次比较都保留小的数,比完后就可以得到最小的数。第二次将余下的数再次两两比较,重复进行,直至剩下最后两个数比较完即排好。由此确定的程序如下:

ORG 0100HSTART:

C CLR 20H

CLR R3,#50

MOV R0,#20H

MOV A,@R0LOOP2: MOV R1,A

MOV R0

INC A,@R0

SUBB A,R1

MOV GOON

JC 20H

SETB A,@R0

XCH R0

DEC A,@R0

XCH R0GOON: INC A,@R0 MOV R3,LOOP2 DJNZ 20H,START JB $ SJMP END 2.5.4子程序能够独立完成一段功能的小程序,称为子程序,例如完成两个字节相加、数制转换、求补码等等。子程序编好以后,存放在ROM的某个地方,当主程序需要时,就可以调用它。有了子程序,能够使主程序更为简练、明朗。子程序在设计时,除了一般程序设计的要求外,还有结合自身的一些注意事项。子程序中必然要用到寄存器和存储单元,如果这些寄存器或存储单元在主程序中已经在使用,那么在调用子程序之前,必须首先把它们存放的内容推入堆栈中保护起来。入栈操作通常在子程序一开始进行,因此,子程序一开始多为入栈指令。当子程序执行完毕返回主程序时,理应要把入栈的内容弹出到相应的寄存器或存储单元中,才不致于影响主程序的执行。出栈可以在返回主程序前进行。子程序从主程序接收到的已知条件称为子程序的入口参数。子程序的运算结果称为出口参数。在调用子程序之前,主程序必须把入口参数设置恰当,满足子程序的要求。子程序也要把出口参数设置恰当,才能让主程序享用。入、出口参数在主、子程序之间传递时,要采取双方均认可并都能接受的方式。实现参数传递有多种方法,常用的有用累加器、用工作寄存器、用堆栈等几种传递参数方法,各种不同的传递参数方法有各自不同的优点。子程序也可以调用子程序,形成嵌套和递归。

【例2-47】

用累加器传递参数。把十六进制数的ASCII码字符转换成十六进制数。 ;对主程序要求:调用前将被转换字符送入A,调用后直接从A中取结果 ;调用子程序标号:ASCIICHANG

;入口参数:要转换的ASCII码字符位于A中 ;出口参数:转换结果放在A中

【例2-48】用工作寄存器传递参数。两个64位无符号数相加。设两数分别放在20H和30H开始的单元中,各占8个字节,相加的和放在从40H开始的单元中。;对主程序的要求:调用前将工作寄存器的内容入栈或暂存于寄存器或存储单元中。调用后直接从工作寄存器获取子程序结果;调用子程序标号:TWOADD;入口参数:将两数的首地址分别送入R0和R1,R0=20H,R1=30H。将字节长度送入R2,R2=08H;出口参数:R0、R1中是相加的和TWOADD:LOOP:ORGMOVMOVMOVCLRINCINCMOVADDCMOVDJNZMOVRET012

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论