Download presentation
Presentation is loading. Please wait.
1
本章小结 5.1 80C51单片机指令系统概述 5.2 80C51单片机寻址方式 5.3 80C51单片机指令系统
2
单片机应用系统也是由硬件和软件组成的,这是与一般的数字逻辑电路系统的不同之处。
机器语言是计算机唯一能识别的语言,用汇编语言和高级语言编写的程序(称为源程序)最终都必须翻译成机器语言的程序(称为目标程序),计算机才能识别。 汇编语言是能够利用单片机所有特性直接控制硬件的唯一语言,对于一些需要直接控制硬件的场合,汇编语言是必不可少的。 但汇编语言不是一种结构化的程序设计语言,对于较复杂的单片机应用系统,它的编写效率很低。
3
为了提高软件的开发效率,许多软件公司致力于单片机高级语言C编译器的开发研究,许多型号的单片机内部ROM已经达到64KB甚至更大,且具备在系统编程(ISP, In System Programmable)功能,进一步推动了C语言在单片机应用系统开发中的应用。 尽管C语言是一种强大而方便的开发工具,但开发人员要达到用C语言快速编出高效且易于维护的单片机系统应用程序,首先必须对C语言有较透彻的掌握,其次还应该对实际单片机硬件系统有深入的理解。
4
C51单片机指令系统概述 实际上汇编语言源程序是由一条条指令(Instruction)组成的,所以首先介绍指令和指令系统。
5
指令的概念 指令是指挥计算机执行某种操作的命令。一条指令可用两种语言形式表示,即机器语言和汇编语言指令。机器语言指令用二进制代码表示,称指令码,又称机器码,计算机能直接识别并加以分析和执行。汇编语言指令用助记符表示,称汇编语言指令,它便于程序员编写和阅读程序,但不能为计算机识别和执行,必须翻译成机器语言指令。 把用汇编语言编写的源程序翻译成机器语言指令的过程称为汇编。这种翻译工具称为汇编程序或汇编器。
6
指令系统说明 一台计算机所有指令的集合,称为该计算机的指令系统,它是表征计算机性能的重要标志。每台计算机都有它自己特有的指令系统。
7
要让计算机做事,就得向计算机发出指令。但计算机只能懂得数字,如对80C51,要将数据5B送到P1口,必须在ROM中某一位置(如1000H)写上这样的机器码:
1000H B 该指令中75表示操作码,90和5B表示操作数,该机器码的意思是将立即数5B送到P1口,P1口锁存器的内部RAM地址为90。指令的第一种格式就是机器码指令格式,也就是说是数字的形式。
8
但这种形式非常难记,于是有另一种格式,助记符格式如下:
MOV P1, #5BH 用助记符表示指令的格式称为汇编指令格式。
9
80C51汇编语言典型的指令格式为: 操作码 [操作数] ;[注释] 注释不参加汇编,不影响汇编结果,应该养成编写程序时加上注释的良好习惯。 例如,一条传送指令的书写格式为: MOV A, 38H ; (38H)→A
10
80C51汇编语言需用40多种助记符表征30多种指令功能。由于功能助记符需定义诸如内部数据存储器、程序存储器、外部数据存储器等,同一种功能需用几个助记符表示(如
数据传送指令MOV、MOVX、MOVC等)。通过这些助记符,与指令中的源地址、目的地址组合成80C51的111条指令。
11
5.1.3 80C51指令系统助记符 80C51单片机指令系统操作码助记符按功能可分为五大类 1)数据传送类指令(7种助记符)
2)算术运算类指令(8种助记符) 3)逻辑运算类指令(10种助记符) 4)控制转移类指令(18种助记符) 5)位操作指令(1种助记符) 详见主教材114页
12
5.1.4 指令系统中的特殊符号 Rn:当前选中的寄存器区的8个工作寄存器R0~R7(n = 0~7)。
指令系统中的特殊符号 Rn:当前选中的寄存器区的8个工作寄存器R0~R7(n = 0~7)。 Ri:当前选中的寄存器区中可作为地址寄存器的两个寄存器R0和R1(i = 0, 1)。
13
指令系统中的特殊符号(续) Direct:内部数据存储单元的8位地址。包含0~127内部存储单元地址和128~255部分存储单元特殊功能寄存器地址。 #data:指令中的8位常数。 #data16:指令中的16位常数。 addr16:用于LCALL和LJMP指令中的16位目的地址,目的地址可指向64KB程序存储器空间。 addr11:用于ACALL和AJMP指令中的11位目的地址,目的地址必须放在与下条指令第一个字节同一个2KB程序存储器的空间之中。
14
指令系统中的特殊符号(续) rel:8位带符号的偏移字节,用于所有的条件转移和SJMP等指令中,偏移字节位于下条指令的第一个字节开始的-128~+127范围内。 @:间接寄存器寻址或基址寄存器的前缀。 /:为操作的前缀,声明对该位取反。 DPTR:数据指针。 Bit:内部RAM和特殊功能寄存器的直接寻址位。
15
5.1.4 指令系统中的特殊符号(续) A:累加器ACC。 B:特殊功能寄存器B,用于乘法和除法指令中。 C:进位标志位。
指令系统中的特殊符号(续) A:累加器ACC。 B:特殊功能寄存器B,用于乘法和除法指令中。 C:进位标志位。 (x):某地址单元中的内容。 ((x)):由(x)寻址的单元中的内容。 →:表示数据的传送方向。 :表示数据交换。
16
5.2 80C51单片机寻址方式 5.2.1 寄存器寻址方式 80C51单片机共有7种寻址方式: MOV A, R2
其机器码的二进制数为EA( ),其最低3位(010)即为工作寄存器R2的地址。 寄存器寻址方式 寄存器寻址是对由指令选定的工作寄存器(R0~R7)进行读/写,由指令操作码字节的最低3位指明所寻址的工作寄存器。
17
5.2.2 直接寻址方式 直接寻址方式是由指令直接给出操作数地址。 直接寻址方式可访问三种地址空间:
直接寻址方式 直接寻址方式是由指令直接给出操作数地址。 直接寻址方式可访问三种地址空间: ●特殊功能寄存器地址空间,这是唯一能寻址特殊功能寄存器的寻址方式。 ●内部数据存储器RAM的00~7F地址空间。 ●特定的位地址空间。 E MOV A,62H
18
5.2.3 寄存器间接寻址方式 寄存器间接寻址方式以寄存器中的内容为地址,该地址中的内容为操作数的寻址方式。
寄存器间接寻址方式 寄存器间接寻址方式以寄存器中的内容为地址,该地址中的内容为操作数的寻址方式。 寄存器间接寻址的存储器空间包括内部数据RAM和外部数据RAM。 内部数据RAM共有128B(52子系列有256B),因此用1字节的R0或R1可寻址整个空间。 MOV
19
外部数据RAM最大可达64KB,仅用R0或R1无法寻址整个空间。为此,在80C51单片机指令中,当用R0或R1对外部数据RAM作间接寻址时,由P2端口提供高8位外部RAM地址,由R0或R1提供低8位地址。 MOVX
20
对外部数据RAM的第二种寻址方式是用16位的DPTR作为寄存器间接寻址。如:
MOVX 是把DPTR所指向的片外RAM单元中的内容送到A中。
21
寄存器间接寻址的其他例子如下: MOV @R0,A ; A内部RAM中以R0为地址的单元
MOVX A,@R1 ; 外部RAM中地址为P2 R1的单元内容A MOVX @DPTR,A ; A外部RAM中以DPTR为地址的单元 PUSH ACC ; SP+1SP,ACC以SP为地址的内部RAM单元 POP 20H ;以SP为地址的内部RAM中的内容20H内部RAM ;单元,SP-1SP
22
立即寻址方式 立即寻址方式由指令直接给出操作数寻址。通常紧跟指令操作码之后的一个或两个字节数,就是寻址所需的操作数。这类指令大都是2B指令,如 7462 MOV A,#62H ;62H A,“#”为立即数指示符号
23
仅有一条是3B指令。它提供2B的立即数,如:
902CA5 MOV DPTR,#2CA5H ;2CA5H DPTR
24
变址间接寻址方式 基址寄存器加变址寄存器间接寻址方式,是80C51指令集所独有的,它是以程序计数器PC或数据指针DPTR作为基址寄存器,以累加器A作为变址寄存器,这二者内容之和为有效地址。 MOVC MOVC
25
相对寻址方式 相对寻址方式以PC的当前值为基准,加上指令中给出的相对偏移量(rel)形成有效转移地址。相对偏移量是一个带符号的8位二进制数,常以补码的形式出现。 JC rel ;设rel=75H, Cy=1
26
位寻址方式 位寻址方式对位地址中的内容作位操作的寻址。由于单片机中只有内部RAM和特殊功能寄存器的部分单元有位地址(两者统一编址,地址空间为00H~FFH),因此位寻址只能对有位地址的这两个空间做寻址操作。 位寻址是一种直接寻址方式,由指令给出直接位地址。但与直接寻址不同之处在于,位寻址只给出位地址,而不是字节地址。 SETB 20H ;120H位 MOV 32H, C ;进位位C32H位 ORL C, 5AH ;C | 5AH位C
27
表5.1 80C51操作数寻址方式和相应寻址空间 寻 址 方 式 寻 址 范 围 寄存器寻址 R0~R7
ACC、B、CY(位)、DPTR(双字节)、AB(双字节) 直接寻址 内部RAM的低128B 特殊功能寄存器 内部RAM中20H~2FH的128位 专用寄存器中的128个可寻址位 寄存器间接寻址 立即寻址 程序存储器(操作码常数) 变址寻址
28
5.3 80C51单片机指令系统 5.3.1 数据传送类指令 1. 内部数据传送指令
数据传送类指令 1. 内部数据传送指令 内部数据传送是指在工作寄存器R0~R7、内部数据存储器RAM、累加器A、16位数据指针DPTR、内部特殊功能寄存器SFR之间的数据传送。共有18条指令。详见主教材 页。
29
2. 外部数据传送指令 外部数据传送是指片外数据RAM和累加器A之间的相互数据传送。 片外数据存储器只能使用寄存器间接寻址方式,有4条指令,详见主教材 页。
30
3. 程序存储器数据传送指令(查表指令) 由于对程序存储器只能读而不能写,因此其数据传送是单向的,即从程序存储器读取数据,且只能向累加器A传送。这类指令共有2条,详见主教材124页。 4. 交换指令 数据交换的传送操作是指两个数据空间的数据交换操作。有全交换XCH、半交换XCHD和自交换SWAP,共5条指令,详见主教材125页。 数据传送类指令一览表见主教材125页表5.2
31
表5.2 数据传送类指令一览表 指令助记符 功 能 简 述 字 节 数 振荡器周期数 MOV A, Rn 寄存器送累加器 1 12
表5.2 数据传送类指令一览表 指令助记符 功 能 简 述 字 节 数 振荡器周期数 MOV A, Rn 寄存器送累加器 1 12 MOV Rn, A 累加器送寄存器 MOV 内部RAM送累加器 A 累加器送内部RAM MOV A, #data 立即数送累加器 2 MOV A, direct 直接寻址字节送累加器 MOV direct, A 累加器送直接寻址字节 MOV Rn, #data 立即数送寄存器 MOV direct, #data 立即数送直接寻址字节 3 24 #data 立即数送内部RAM
32
MOV direct, Rn 寄存器送直接寻址字节 2 24 MOV Rn, direct 直接寻址字节送寄存器 MOV 内部RAM送直接寻址字节 direct 直接寻址字节送内部RAM MOV direct, direct 直接寻址字节送直接寻址字节 3 MOV DPTR, #data16 16位立即数送数据指针
33
指令助记符 功 能 简 述 字 节 数 振荡器周期数 MOVX 外部RAM送累加器(8位地址) 2 24 A 累加器送外部RAM(8位地址) 1 MOVX 外部RAM送累加器(16位地址) A 累加器送外部RAM(16位地址) MOVCA, A+DPTR 程序代码送累加器(相对数据指针) MOVC 程序代码送累加器(相对程序计数器)
34
XCH A, Rn 累加器与寄存器交换 1 24 XCH 累加器与内部RAM交换 12 XCH A, direct 累加器与直接寻址字节交换 2 XCHD 累加器与内部RAM低4位交换 SWAP A 累加器高4位与低4位交换 POP direct 栈顶弹至直接寻址字节 PUSH direct 直接寻址字节压入栈顶
35
5.3.2 算术运算类指令 算术运算指令的主要功能是实现算术加、减、乘、除等运算。 1. ADD类指令
算术运算类指令 算术运算指令的主要功能是实现算术加、减、乘、除等运算。 1. ADD类指令 ADD类指令是不带进位的加法运算指令,共有4条 ADD A,Rn ; A+RnA, Rn寄存器内容加到A中 ADD A,direct ; A+(direct) A, 直接地址内容加到A中 ADD ; A+(Ri)A, 间址内容加到A中 ADD A,#data ; A+dataA, 立即数加到A中
36
ADDC类指令是带进位的加法运算指令,共有4条
ADDC A,Rn ; A+Rn+CYA, Rn寄存器内容和进位位状态一并加到A中 ADDC A,direct ; A+(direct)+CY A, 直接地址内容和进位位状态一并加到A中 ADDC ; A+(Ri)+CY A, 间址内容和进位位状态一并加到A中 ADDC A, #data ; A+data+CY A, 立即数和进位位状态一并加到A中
37
【例5.6】 编写计算1234H+0FE7H的程序,将结果存入内部RAM 4lH和40H单元,40H存低8位,4lH中存高8位。
程序如下: MOV A, #34H ;被加数低8位数34H送A ADD A, #0E7H ;加数低8位数E7H与之相加, A=lBH, CY=1 MOV 40H, A ;A40H, 即34H+E7H结果存入40H中, (40H)=1BH MOVA, #12H ;被加数高8位数12H送A ADDC A, #0FH ;加数高8位0FH和CY与A相加, A=22H MOV 4lH, A ;高8位与进位位之和存入4lH中, (41H)=22H ;总和为221BH, 总结果在4lH, 40H单元中
38
SUBB类指令是带借位减法指令,其功能是将A中的被减数减去源操作数指出的内容,再减去借位标志CY(原进位标志)状态,差值在A中。
SUBB A, Rn ; A-Rn-CYA, A减寄存器Rn内容及进位 标志存到A中 SUBB A, direct ; A- (direct)-CYA, A减寄存器直接地址内 容及进位标志存到A中 SUBB A, @Ri ; A-(Ri)-CYA, A减间址内容及进位位状 态一并存到A中 SUBB A, #data ; A-data-CYA, A减立即数及进位位状态 一并加到A中 减法运算在计算机中实际是补码相加方式。
39
4. 乘(MUL)和除(DIV)指令 MUL AB ; A×B A和B, 结果是16位, 高8位存入B中, 低8位在A中 DIV AB ; A/BA和B,商存入A,余数存入B
40
5. INC(加1)和DEC(减1)类指令 INC A ; A+1A, A加1 INC Rn ; Rn+1Rn, Rn中内容加1
INC direct ; (direct)+1(direct), 直接地址中内容加1 ; (Ri)+1(Ri), Ri间址中的内容加1 INC DPTR ; DPTR+1DPTR, 数据指针加1 DEC A ; A-1A, A减1 DEC Rn ; Rn-1Rn, Rn中内容减1 DEC direct ; (direct)-1(direct), 直接地址中的内容减1 ; (Ri)-1(Ri), Ri间址中的内容减1
41
功能是把A中二进制码自动调整成二-十进制码(BCD码)。用于队BCD码的加法结果进行调整。
6. 十进制调整指令 DA A 功能是把A中二进制码自动调整成二-十进制码(BCD码)。用于队BCD码的加法结果进行调整。 例如: MOV A, #05H ; 05HA ADD A, #08H ; A+08HA DA A ; 调整 结果:A = 13(BCD码)。
42
表5.3 算术操作类指令一览表 (主教材128页) 指令助记符 功能简述 字节数 振荡器周期数 ADD A, Rn 累加器加寄存器 1 12
表5.3 算术操作类指令一览表 指令助记符 功能简述 字节数 振荡器周期数 ADD A, Rn 累加器加寄存器 1 12 ADD 累加器加内部RAM ADD A, direct 累加器加直接寻址字节 2 ADD A, #data 累加器加立即数 ADDC A, Rn 累加器加寄存器和进位位 ADDC 累加器加内部RAM和进位位 ADDC A, #data 累加器加立即数和进位位 ADDC A, direct 累加器加直接寻址字节和进位位 INC A 累加器加1 INC Rn 寄存器加1 INC direct 直接寻址字节加1 内部RAM加1 INC DPTR 数据指针加1 24 DA A 十进制调整 (主教材128页)
43
表5.3 算术操作类指令一览表(续) (主教材128页) 指令助记符 功能简述 字节数 振荡器周期数 DA A 十进制调整 1 12
表5.3 算术操作类指令一览表(续) 指令助记符 功能简述 字节数 振荡器周期数 DA A 十进制调整 1 12 SUBB A, Rn 累加器减寄存器和借位 SUBB 累加器减内部RAM和借位 SUBB A, #data 累加器减立即数和借位 2 SUBB A, direct 累加器减直接寻址字节和借位 DEC A 累加器减1 DEC Rn 寄存器减1 间接RAM减1 DEC direct 直接寻址字节减1 MUL AB 累加器A乘寄存器B 48 DIV AB 累加器A除以寄存器B (主教材128页)
44
逻辑运算类指令 这类指令主要用于对两个操作数按位进行逻辑操作,结果送到累加器A或直接寻址单元。这类指令所能执行的操作主要有:与、或、异或以及移位、取反、清除等。执行这些指令时一般不影响程序状态字寄存器PSW,仅当目的操作数为ACC时对奇偶标志位有影响。逻辑运算类指令共有24条。
45
1. 逻辑与(ANL)指令 逻辑与指令的功能是将源操作数内容和目的操作数内容按位相与,结果存入目的操作数指定单元,源操作数不变,执行后影响奇偶标志位P。 ANL A, Rn ; A & RnA ANL A, direct ; A & (direct)A ANL ; A & (Ri)A ANL A, #data ; A & dataA ANL direct, A ; (direct) & A(direct) ANL direct, #data ; (direct) & data(direct)
46
2. 逻辑或(ORL)指令 逻辑或指令的功能是将源操作数内容与目的操作数内容按位逻辑或,结果存入目的操作数指定单元中,源操作数不变,执行后影响奇偶标志位P。 ORL A, Rn ; A | RnA ORL A, direct ; A | (direct)A ORL A, @Ri ; A | (Ri)A ORL A, #data ; A | dataA ORL direct, A ; (direct)| A(direct) ORL direct, #data ; (direct) | data(direct)
47
3. 逻辑异或(XRL)指令 异或指令的功能是将两个操作数的指定内容按位异或,结果存于目的操作数指定单元中。异或原则是相同为0,相异为1,执行后影响奇偶标志位P。 XRL A, Rn ; A ^ RnA XRL A, direct ; A ^ (direct)A XRL ; A ^ (Ri)A XRL A, #data ;A ^ dataA XRL direct, A ; (direct) ^ A(direct) XRL direct, #data ; (direct) ^ data(direct)
48
4. 循环移位指令 循环移位指令的功能是,将累加器A中内容循环移位或者和进位位一起移位,指令共4条。 RL A ; A中内容循环左移, 执行本指令一次左移一位 RR A ; A中内容循环右移, 执行本指令一次右移一位 RLC A ; A与CY内容一起循环左移一位, 执行本指令 ;一次左移一位 RRC A ; A与CY内容一起循环右移一位, 执行本指令 ;一次右移一位 循环操作具体见主教材131页
49
表5.4 逻辑运算类指令一览表见主教材132页
50
控制转移类指令 1. 无条件转移类指令 LJMP add16 ; addl6PC无条件跳转到addl6地址可在64KB范 围内转移, 称为长转移指令 AJMP add11 ; addl1PC无条件转向到addl1地址可在2KB范围 内转移, 称为绝对转移指令 SJMP rel ; PC+2+relPC相对转移, rel是偏移量, 它是8位 有符号数, 范围-128~+127即向后跳转128B, 向前 可跳转127B ; A+DPTRPC, 属散转指令, 无条件转向 A与DPTR内容相加后形成的新地址
51
这类指令先测试某一条件是否满足,满足规定的条件时,程序转移到指定地址,否则将继续执行下一条指令。条件是由条件转移指令本身提供(或规定)的。
2. 条件转移类指令 JZ rel JNZ rel CJNE A, direct, rel CJNE A, #data, rel CJNE Rn, #data, rel CJNE @Ri, #data, rel DJNZ Rn, rel DJNZ direct, rel 这类指令先测试某一条件是否满足,满足规定的条件时,程序转移到指定地址,否则将继续执行下一条指令。条件是由条件转移指令本身提供(或规定)的。
52
3. 调用、返回、空操作指令 LCALL addr16 ACALL addr11 RET RETI NOP
53
表5.5 控制程序转移类指令一览表 (主教材135页) 指令助记符 功 能 简 述 字 节 数 振荡器周期数 ACALL addr11
表5.5 控制程序转移类指令一览表 (主教材135页) 指令助记符 功 能 简 述 字 节 数 振荡器周期数 ACALL addr11 2KB内绝对调用 2 21 AJMP addr11 2KB内绝对转移 24 LCALL addr16 64KB内长调用 3 LJMP addr16 64KB内长转移 SJMP rel 相对短转移 相对长转移 1 RET 子程序返回 RETI 中断返回 JZ rel 累加器为0转移 JNZ rel 累加器为非0转移 CJNE A,#data,rel 累加器与立即数不等转移 CJNE A,direct,rel 累加器与直接寻址字节不等转移 CJNE Rn,#data,rel 寄存器与立即数不等转移 内部RAM与立即数不等转移 DJNZ Rn,rel 寄存器减1不为0转移 DJNZ direct,rel 直接寻址字节减1不为0转移 NOP 空操作 12
54
位操作指令 单片机都具有较强的位处理功能,可以对片内位地址区及某些特殊功能寄存器的位进行位操作。在80C51的硬件结构中,有个位处理器(布尔处理器),它具有一套处理位变量的指令集,包括位变量传送、逻辑运算、控制程序转移等指令。
55
在80C51单片机的内部数据存储器中,20H~2FH为位操作区域,其中每位都有自己的位地址(参见主教材90-91页第4章部分),可以对每一位进行操作。位地址空间为00H~7FH,共16 8=128位,如主教材中136页表5.6所示。对于字节地址能被8整除的特殊功能寄存器的每一位,也具有可寻址的位地址,如主教材中137页表5.7所示。
56
表5.8 布尔变量操作类一览表 主教材中139页 指令助记符 功能简述 字节数 振荡器周期数 MOV C, bit 直接寻址位送CY 2
表5.8 布尔变量操作类一览表 主教材中139页 指令助记符 功能简述 字节数 振荡器周期数 MOV C, bit 直接寻址位送CY 2 12 MOV bit, C CY送直接寻址位 CLR C CY清0 1 CLR bit 直接寻址位清0 CPL C CY取反 CPL bit 直接寻址位取反 SETB C CY置位 SETB bit 直接寻址位置位 ANL C, bit CY逻辑与直接寻址位 24 ANL C, /bit CY逻辑与直接寻址位的反 ORL C, bit CY逻辑或直接寻址位 ORL C, /bit CY逻辑或直接寻址位的反 JC rel CY置位转移 JNC rel CY清0转移 JB bit, rel 直接寻址位为1转移 JNB bit, rel 直接寻址位为0转移 3 JBC bit, rel 直接寻址位为1转移并清该位
57
C51汇编语言程序设计 前面几节中介绍了80C51单片机的指令系统,所有汇编指令均能翻译成机器码, 即有一条汇编指令, 就有一条机器指令码与之对应。如何使用单片机的汇编指令编写程序,是本节所要介绍的内容。下面先了解一下汇编语言的特点和语句格式。
58
1. 汇编语言的特点 ※ 汇编语言编写的程序占用存储空间小,运行速度快,能编写出最优化的程序。 ※ 使用汇编语言编程比使用高级语言困难。
※ 汇编语言能直接访问存储器及接口电路,也能处理中断,因此汇编语言程序能直接管理和控制硬件设备。 ※ 汇编语言缺乏通用性,程序不易移植,各种计算机都有自己的汇编语言,不同计算机的汇编语言之间不能通用。
59
汇编语句由标号、操作码、操作数和注释四个部分所组成,其中方括号中是可选择部分,视需要而定。
2. 汇编语言的语句格式 80C51汇编语言的语句格式表示如下: [<标号>:]<操作码>[<操作数>];[<注释>] 汇编语句由标号、操作码、操作数和注释四个部分所组成,其中方括号中是可选择部分,视需要而定。
60
编写汇编语言程序时,还会用到另一类指令,这类指令仅供汇编程序将源程序翻译成目标程序时使用,本身并不形成机器码,这类指令称为伪指令。
61
3. 汇编语言源程序的汇编方式 把用汇编语言书写的源程序翻译成机器语言目标程序的过程称为汇编。汇编通常划分为三种方式:手工汇编、自汇编及交叉汇编。 在一般简易型开发装置中,常常采用交叉汇编的方法。
62
5.4.1 伪指令 设置起始地址ORG(Origin) 定义字节DB或DEFB(Define Byte)
伪指令 设置起始地址ORG(Origin) 定义字节DB或DEFB(Define Byte) 定义字DW或DEFW(Define Word) 为标号赋值EQU(Equate) 结束汇编END
63
汇编语言程序设计举例 建立数学模型 给出数学模型的解题算法 画出流程图 写出源程序 编译成目标程序 运行调试目标程序
64
【例5.14】 循环程序设计:将地址从50H开始的16个单元清0,如图所示。
内容 5FH 00H … 54H 53H 52H 51H 50H R0
65
(1)流程图如图所示。
66
(2)源程序: 该程序将MOV @R0, #00H操作重复进行了16次, 故为典型的循环程序。
DATA_ADDR EQU #50H ;数据块首地址 COUNT EQU #10H ;循环次数 NUMBER EQU #00H ;赋值0 ORG 100H MOV R0,DATA_ADDR ;数据块首地址DATA_ADDR赋给地址指针R0 MOV R2, COUNT ;循环次数0AH赋给计数器R2 LOOP: NUMBER ;给((R0))单元赋值NUMBER INC R ;地址指针R0加1 DEC R ;计数器R2减1 CJNE R2, #00H, LOOP ;判R2是否为0,非0转LOOP继续清0 SJMP $ ;R2为0,循环结束 #00H操作重复进行了16次, 故为典型的循环程序。
67
C51单片机C51程序设计语言 随着80C51单片机硬件性能的提升,尤其是片内程序存储器容量的增大和时钟工作频率的提高,已基本克服了高级语言产生代码长、运行速度慢、不适合单片机使用的致命缺点。由此C51已经得到广泛的推广和应用, 采用C51程序设计语言,编程者只需了解变量和常量的存储类型与80C51单片机存储空间的对应关系,而不必深入了解单片机的硬件和接口。C51编译器会自动完成变量的存储单元的分配。
68
1. C语言编程与汇编语言编程相比的优势 1)编程调试灵活方便 2)生成的代码编译效率高 3)完全模块化 4)可移植性好 5)便于项目维护管理
69
2. C51语言编译器与标准ANSI C编译器的主要区别
70
C51的特点和功能主要是80C51单片机自身特点引起的。
数据类型:由于80C51系列器件包含了位操作空间和丰富的位操作指令,因此 C51比ANSI C多一种位类型
71
数据存储类型:80C51系列单片机有程序存储器和数据存储器。数据存储器又分片内和片外数据存储器。片内数据存储器还分直接寻址区和间接寻址区,分别对应code、data、idata、xdata以及根据80C51系列特点而设定的pdata类型。
72
数据运算操作和程序控制:从数据运算操作和程序控制语句以及函数的使用上来讲,它们几乎没有什么明显的区别。只是在函数的使用上,由于单片机系统的资源有限,它的编译系统不允许太多的程序嵌套。
C51与标准ANSI C库函数:部分库函数不适合单片机处理系统,因此被排除在外,如字符屏幕和图形函数。
73
5.5.1 C51的标识符和关键字 标识符用来标识源程序中某个对象的名字,这些对象可以是语句、数据类型、函数、变量、数组等。
标识符区分大小写,第一个字符必须是字母或下划线。 C51中有些库函数的标识符是以下划线开头的,所以一般不要以下划线开头命名标识符。 ANSI C标准关键字和C51编译器的扩展关键字一览表见主教材 页。
74
5.5.2 C51编译器能识别的数据类型 数 据 类 型 长 度 大 小 unsigned char 1B 0~255 char
长 度 大 小 unsigned char 1B 0~255 char -128~+127 unsigned int 2B 0~65535 int -32768~+32767 unsigned long 4B 0~ long ~ float E-38~ E+38 * 1B~3B 对象的地址 bit 位 0或1 sfr sfr16 sbit
75
变量的存储种类和存储器类型 变量是一种在程序执行过程中,其数值不断变化的量。同ANSI C一样,C51规定变量必须先定义后使用。C51对变量的进行定义的格式如下: [存储种类] 数据类型 [存储器类型] 变量名表 其中,存储种类和存储器类型是可选项。
76
存储种类是指变量在程序执行过程中的作用范围。变量的存储种类有四种,分别为:
自动(auto) 外部(extern) 静态(static) 寄存器(register)
77
使用外部种类存储符extern定义的变量称为外部变量。在一个函数体内,要使用一个已在该函数体外或别的程序模块文件中定义过的外部变量时,该变量在本函数体内要用extern说明。
当片内RAM资源紧张时,不建议将外部变量放在片内RAM。
78
使用存储种类说明符static定义的变量称为静态变量。静态变量分为局部静态变量和全局静态变量。
局部静态变量是在两次函数调用之间仍能保持其值的局部变量。有些程序要求在多次调用之间仍然保持变量的值,使用自动变量无法作用到这一点。使用全局变量有时会带来意外的副作用,这时可采用局部静态变量。
79
【例5.15】局部静态变量的使用——计算并输出1~8的阶乘值。
80
使用存储种类说明符register定义的变量称为寄存器变量。80C51访问寄存器的速度最快,通常将使用频率最高的那些变量定义为寄存器变量。C51编译器能自动识别程序中使用频率最高的变量,并自动将其作为寄存器变量,用户无需专门声明。
81
2. 存储器类型 定义变量时,除了说明存储种类外,还允许说明变量的存储器类型。存储器类型和存储种类是完全不同的概念,存储器类型指明该变量所处的单片机的内存空间。C51编译器可识别以下存储器类型,如下表所示。
82
存储器类型 描 述 data 直接寻址的片内数据存储器低128B,访问速度最快 bdata 可位寻址的片内数据存储器(地址20H~2FH共16B)允许位和字节混合访问 idata 间接寻址片内数据存储器256B。允许访问片内全部地址 pdata xdata code
83
如果在变量定义时省略了存储器类型标识符,C51编译器会选择默认的存储器类型。默认的存储器类型由SMALL、COMPACT和LARGE存储模式指令决定。
84
1)data区 对data区的寻址是最快的,所以应该把使用频率高的变量放在data区,由于空间有限,必须注意使用data区,data区除了包含程序变量外,还包含了堆栈和寄存器组data区。 在SMALL存储模式下,未说明存储器类型时,变量默认被定位在data区。
85
2)bdata区 当在DATA区的位寻址区定义变量,这个变量就可进行位寻址,并且声明位变量。这对状态寄存器来说十分有用,因为它可以单独使用变量的每一位,而不一定要用位变量名引用位变量。 3)idata区 idata区也可以存放使用比较频繁的变量,使用寄存器作为指针进行寻址。在寄存器中设置8位地址进行间接寻址,与外部存储器寻址比较,它的指令执行周期和代码长度都比较短。
86
4)pdata和xdata区 在这两个区声明变量和在其他区的语法是一样的,pdata区只有256B,而xdata区可达65536B 5)code区 code区即80C51的程序代码区,所以代码区的数据是不可改变的,80C51的代码区不可重写。一般代码区中可存放数据表,跳转向量和状态表
87
3. 存储模式 C51编译器允许采用三种存储模式:小编译模式SMALL、紧凑编译模式COMPACT、大编译模式LARGE。
88
一个变量的存储器模式确定了未声明存储器类型的变量在内存中的地址空间。在SMALL模式下,该变量在80C51单片机的内部RAM中;在COMPACT和LARGE模式下,该变量在80C51单片机的外部RAM中。 建议在编写源程序时,把存储模式设定为SMALL,再在程序中把xdata、pdata和idata等类型变量进行专门声明。
89
5.5.4 绝对地址的访问 1. 使用指针 采用指针的方法,可实现在C51程序中对任意指定的存储器地址进行操作。
绝对地址的访问 1. 使用指针 采用指针的方法,可实现在C51程序中对任意指定的存储器地址进行操作。 uchar idata ivar1; uchar xdata *xdp; /*定义一个指向xdata存储器空间的指针*/ char data *dp; /*定义一个指向DATA存储器空间的指针*/ uchar idata *idp; /*定义一个指向idata存储器空间的指针*/ xdp=0x1000; /*xdata指针赋值,指向xdata存储器地址1000H处*/ *xdp=0x5A; /*将数据5AH送到xdata的1000H单元*/ dp=0x61; /*DATA指针赋值,指向DATA存储器地址61H处*/ *dp=0x23; /*将数据23H送到DATA的61H单元*/ idp=&ivar1; /*idp指向idata区变量ivar1*/ *idp=0x16; /*等价于ivar1=0x16*/
90
2. 使用C51运行库中预定义宏 #define CBYTE((unsigned char volatile *)0x50000L)
#define DBYTE((unsigned char volatile *)0x40000L) #define PBYTE((unsigned char volatile *)0x30000L) #define XBYTE((unsigned char volatile *)0x20000L) #define CWORD((unsigned int volatile *)0x50000L) #define DWORD((unsigned int volatile *)0x40000L) #define PWORD((unsigned int volatile *)0x30000L) #define XWORD((unsigned int volatile *)0x20000L) 例如 ui_var1 = XWORD [0x0002]; /*访问外部 RAM 0004H~0005H地址的内容*/ uc_var1 = XBYTE [0x0002]; /*访问外部 RAM 0002H地址的内容*/
91
3. 使用C51扩展关键字 _at_ 使用_at_对指定的存储器空间的绝对地址进行定位,一般格式如下: [存储器类型] 数据类型 标识符 _at_ 常数 例如 uchar xdata xram[0x8000] _at_ 0x0000; /*在外部RAM空间0000H处定义了一个一维数组 使用_at_定义的变量只能为全局变量。
92
中断服务程序 80C51的中断系统十分重要,C51编译器允许在C语言源程序中声明中断和编写中断服务程序,从而减轻了采用汇编程序编写中断服务程序的繁琐程度。
93
通过使用interrupt关键字来实现。定义中断服务程序的一般格式如下:
void 函数名( ) interrupt n [using m] using m指明该中断服务程序所对应的工作寄存器组,取值范围:0~3。指定工作寄存器组的缺点是所有被中断调用的过程都必须使用同一个寄存器组,否则参数传递会发生错误。通常不设定using m。
94
关键字interrupt后面的n是中断号,n的取值范围:0~31。编译程序从8n+3处产生中断向量,即在程序存储器8n+3地址处形成一条长跳转指令,转向中断号n的中断服务程序。
中 断 源 中 断 向 量 外部中断0 0003H 1 定时器0 000BH 2 外部中断1 0013H 3 定时器1 001BH 4 串行口 0023H
95
设置一个定时器中断服务程序的例子如下: #include <reg51.h> #include <stdio.h> #define RELOADTH 0x3C #define RELOADTL 0xB0 extern unsigned int time0_counter; void timer0(void) interrupt 1{ TR0=0; /*停止定时器0*/ TH0=RELOADTH; /* 50ms后溢出*/ TL0=RELOADTL; TR0=1; /*启动T0*/ time0_counter++; /*中断次数计数器加1*/ printf(“time0_counter=%05d\n”,time0_counter); } 使用C51编写中断服务程序,程序员无需关心ACC、B、DPH、DPL、PSW等寄存器的保护,C51编译器会根据上述寄存器的使用情况在目标代码中自动增加压栈和出栈。
96
5.6 C51的运算符和表达式 运算符就是完成某种特定运算的符号。运算符按其表达式中与运算符的关系可分为单目运算符、双目运算符和三目运算符。
97
5.6.1 赋值运算符 使用“=”的赋值语句格式如下: 变量 = 表达式;
赋值运算符 使用“=”的赋值语句格式如下: 变量 = 表达式; 需要注意“==”与“=”两个符号的区别,有时编译报错,往往就是错在if(b = 0xff)之类的语句中,错将“==”用为“=”。“==”符号是用来进行相等关系的运算。
98
5.6.2 算术运算符 + 加或取正值运算符 - 减或取负值运算符 * 乘运算符 / 除运算符
算术运算符 + 加或取正值运算符 - 减或取负值运算符 * 乘运算符 / 除运算符 % 模(取余)运算符,如8 % 5 = 3,即8除以5的余数是3
99
5.6.3 关系运算符 C51中有6种关系运算符: > 大于 < 小于 >= 大于等于 <= 小于等于
关系运算符 C51中有6种关系运算符: > 大于 < 小于 >= 大于等于 <= 小于等于 == 测试等于 != 测试不等于
100
逻辑运算符 逻辑与:条件式1 && 条件式2。 逻辑或:条件式1 || 条件式2。 逻辑非:!条件式。
101
5.6.5 位运算符 C51中共有6种位运算符: & 按位与 | 按位或 ^ 按位异或 ~ 按位取反 << 左移
位运算符 C51中共有6种位运算符: & 按位与 | 按位或 ^ 按位异或 ~ 按位取反 << 左移 >> 右移
102
5.6.6 复合运算符 复合运算符就是在赋值运算符“=”的前面加上其他运算符。以下是C51语言中的复合赋值运算符:
复合运算符 复合运算符就是在赋值运算符“=”的前面加上其他运算符。以下是C51语言中的复合赋值运算符: += 加法赋值 >>= 右移位赋值 -= 减法赋值 &= 逻辑与赋值 *= 乘法赋值 |= 逻辑或赋值 /= 除法赋值 ^= 逻辑异或赋值 %= 取模赋值 ~= 逻辑非赋值 <<= 左移位赋值
103
指针和地址运算符 指针是C语言中十分重要的概念,也是学习C51语言中的一个难点。C51语言中提供的两个专门用于指针和地址的运算符: * 取内容 & 取地址 取内容和取地址运算的一般形式分别为: 变量 = * 指针变量 指针变量 = & 目标变量
104
5.7 C51的库函数 C51的强大功能及其高效率的重要体现之一在于,其提供了丰富的可直接调用的库函数。使用库函数使程序代码简单、结构清晰、易于调试和维护,下面介绍C51的库函数系统。
105
本征库函数和非本征库函数 C51提供的本征函数在编译时直接将固定的代码插入当前行,而不是用ACALL和LCALL语句实现的,这样就大大提供了函数访问的效率,而非本征函数则必须由ACALL及LCALL调用。
106
C51的本征库函数只有9个,数目虽少,但都非常有用,现罗列如下:
_crol_,_cror_:将char型变量循环向左(右)移动指定位数后返回。 _iror_,_irol_:将int型变量循环向左(右)移动指定位数后返回。 _lrol_,_lror_:将long型变量循环向左(右)移动指定位数后返回。 _nop_:相当于插入汇编指令NOP。 _testbit_:相当于JBC bitvar测试该位变量并跳转同时清除。 _chkfloat_: 测试并返回源点数状态。 使用上述函数时,源程序开头必须包含 #inclucle <intrins.h>一行。
107
几类重要的库函数 C51提供了丰富的库函数资源,包括大量的关于I/O操作、内存分配、字符串操作、据类型转换、数学计算等函数库。它们是以执行代码的形式出现,供用户在连接定位时用。在用预处理器命令#include包含相应的头文件后,就可以在程序中使用这些函数。
108
1. 内部函数intrins.h 这个库中提供的是一些用汇编语言编写的函数。用汇编语言编写非常直接简单且目代码很短,而用C51编写则代码很长。这些函数主要有: _crol_/_cror_ 无符号字符型变量左/右移位函数 _irol_/_iror_ 无符号整型变量左/右移位函数 _lrol_/_lror_ 无符号长整型变量左/右移位函数 _nop_ 空操作函数 _testbit_ 位测试函数
109
举例: #inclucle <intrins.h> void main() { unsigned int y; y=0x00ff; y=_irol_(y,4); } 运行后,y=0x0ff0。
110
2. 绝对地址访问函数absacc.h 用预处理器伪指令#define为各空间的绝对地址定义宏数组名如下:
#define CBYTE((unsigned char*)0x500000L)/*code空间*/ #define DBYTE((unsigned char*)0x400000L)/*data空间*/ #define PBYTE((unsigned char*)0x300000L)/*pdata空间*/ #define XBYTE((unsigned char*)0x200000L)/*xdata空间*/ 以上存取对象是char类型字节。
111
DBYTE[0x10] 表示data空间绝对地址16处的字节对象,XWORD[0xff] 表示xdata空间绝对地址255处的字对象。
#define CWORD((unsigned int*)0x500000L)/*code空间*/ #define DWORD((unsigned int*)0x400000L)/*data空间*/ #define PWORD((unsigned int*)0x300000L)/*pdata空间*/ #define XWORD((unsigned int*)0x200000L)/*xdata空间*/ 以上存取对象是int类型字。 DBYTE[0x10] 表示data空间绝对地址16处的字节对象,XWORD[0xff] 表示xdata空间绝对地址255处的字对象。
112
3. 缓冲区处理函数string.h 1)计算字符串s的长度 strlen 原型:extern int strlen(char *s);
说明:返回s的长度,不包括结束符NULL。 举例: #include <string.h> main() { char *s="Golden Global View"; printf("%s has %d chars",s,strlen(s)); getchar(); return 0; }
113
2)由src所指内存区域复制count个字节到dest所指 内存区域。
memcpy 原型:extern void *memcpy(void *dest, void *src, unsigned int count); 说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。 举例: #include <string.h> main() { char *s="Golden Global View"; char d[20]; memcpy(d,s,strlen(s)); d[strlen(s)]=0; printf("%s",d); getchar(); return 0; }
114
3)由src所指内存区域复制count个字节到dest所指内存区域
原型:extern void *memmove(void *dest, const void *src, unsigned int count); 说明:与memcpy工作方式相同,但src和dest所指内存区域可以重叠,但复制后src内容会被更改。函数返回指向dest的指针。 4)比较内存区域buf1和buf2的前count个字节 原型:extern int memcmp(void *buf1, void *buf2, unsigned int count);
115
5)把buffer所指内存区域的前count个字节设置成字符c
原型:extern void *memset(void *buffer, int c, int count); 说明:返回指向buffer的指针。 #include <string.h> main() { char *s="Golden Global View"; memset(s,'G',6); printf("%s",s); getchar(); return 0; }
116
6)从buf所指内存区域的前count个字节查找字符ch
原型:extern void *memchr(void *buf, char ch, unsigned count); 说明:当第一次遇到字符ch时停止查找。如果成功,返回指向字符ch的指针;否则返回NULL。
117
5.8 C51的应用技巧 灵活选择变量的存储器类型 避免使用浮点变量 灵活设置变量,高效利用存储器 为变量分配内部存储区 使用库函数
使用宏替代函数 存储器模式的确定 详见主教材169页
118
本章小结 指令是指挥计算机执行某种操作的命令。一台计算机所有指令的集合,称为该计算机的指令系统,它是表征计算机性能的重要标志,每台计算机都有它自己特有的指令系统。 用助记符表示的指令称为汇编语言指令,汇编语言源程序是由一条条汇编语言指令组成的。汇编语言指令格式为: 标号:指令助记符 操作数 ;注解
119
操作数与寻址方式对照表 操 作 数 寻 址 方 式 表 示 符 号 立即数 立即寻址 #data 寄存器 寄存器寻址 R0~R7 存储单元
操 作 数 寻 址 方 式 表 示 符 号 立即数 立即寻址 #data 寄存器 寄存器寻址 R0~R7 存储单元 直接寻址 direct 寄存器间接寻址 ((Ri)) 变址间接寻址 (PC)+(A)或(DPTR)+(A) 位操作数 位寻址 bit 相对偏移量 相对寻址 rel
120
80C51单片机的指令按功能可分为传送、算术、逻辑、位处理和转移指令。
122
逻辑运算指令包括逻辑运算和移位指令。 在双操作数的逻辑运算指令中累加器A总是作为目的操作数,而源操作数S=#dat A循环左移指令为: RL A,A带进位循环左移指令为:RLC A, A循环右移指令RR A和A带进位循环右移指令为:RRC A。
123
4. 位处理指令 位处理指令分为位传送、位修改、位逻辑三类。
124
C51即80C51单片机的C语言。采用C51程序设计语言,编程者只需了解变量(常量)的存储器类型与80C51单片机存储空间的对应关系,而不必深入了解80C51单片机寻址方式,C51编译器会自动完成变量(常量)的存储单元的分配,并产生最为合适的目标代码。主教材174页表5.16 示出了存储器、存储器类型和访问速度和寻址方式对照表。
125
[存储种类] 数据类型 [存储器类型] 变量名表
C51规定变量必须先定义后使用。C51对变量进行定义的格式如下: [存储种类] 数据类型 [存储器类型] 变量名表 存储种类是可选项,有4种,分别为:自动(auto)、外部(extern)、静态(static)和寄存器(register)。 存储器类型指明该变量所处的单片机的内存空间。分别为bdata、data、idata、xdata 。
126
80C51单片机的机器指令只支持字节和位变量,尽可能选择的变量类型应该是char或bit,它们只占用1B或1位。除了根据变量长度来选择变量类型以外,还要考虑该变量是否会用于负数的场合,如果程序中可以不需要负数,那么可把变量都定义成无符号类型的。
Similar presentations