此篇文章中涉及的新指令如下:
数量 助记符 说明 字节数 执行时间 指令代码
63,DIV AB 累加器除以B,A存商,B存余数 1 4 84H
64,ORL direct,#data 立即数逻辑或到直接寻址字节 3 2 43H,direct,data
65,LCALL addr16 长调用子程序 3 2 12H,addr(15-8)addr(7-0)
66,ORL A,#data 立即数逻辑或到累加器A 2 1 44H,data
67,JNC rel 进位标志位为0,则转移 2 2 50H,rel
68,INC direct 直接寻址字节中的内容增1 2 1 05H,direct
69,RR A 累加器A循环右移 1 1 03H
70,XCH A,direct 直接寻址字节中的内容与累加器A中的内容互换 2 1 C5H,direct
71,JC rel 进位标志位为1,则转移 2 2 40H,rel
72,MOV direct1,direct2 direct2中的内容送到direct1中去 3 2 85H,direct2,direct1
73,XCHD A,@Ri 间接寻址RAM单元和累加器低半字节内容交换 1 1 D6H-D7H
74,XRL A,Rn 寄存器逻辑异或到累加器A 1 1 68H-6FH
75,JNB bit,rel 直接寻址位为0,则转移 3 2 30H,rel
76,CPL A 累加器A中的内容取反 1 1 F4H
77,JZ rel 累加器A中内容为0,则转移 2 2 60H,rel
78,ADDC A,direct 直接寻址字节内容加到累加器A(带进位) 2 1 35H,direct
51单片机中常用的伪指令(伪指令是用于对汇编过程进行某种控制或对符号和标号进行赋值,这些指令不属于指令系统中的指令,汇编时不产生机器代码)
伪指令符号,名称 功能 格式
ORG 汇编起始地址伪指令 用于定义汇编以后的目标程序的起始地址 [标号:] ORG addr16
END 汇编结束伪指令 用于表示汇编语言源程序结束 [标号:]END
EQU 赋值伪指令 用于对程序中出现的标号进行赋值 字符名称 EQU 数或汇编符号(先定义后使用)
DATA 数据地址赋值伪指令 用于对数据地址或代码地址赋予规定的字符名称 标号名称 DATA 表达式
DB,DW,DS 定义字节,字,空间伪指令 [标号:] DB/DW/DS 字节常数/字常数,表达式
BIT 位地址符号伪指令 用于将位地址赋给字符名称 字符名称 BIT 位地址
题14
将片外RAM的20H单元中的压缩BCD码拆成两个ASCII码存入片内符号为BCDL,BCDH中,低四位存BCDL,高四位存BCDH。(BCDL,BCDH是字符名称,具体地址自行定义)
解析:
压缩BCD码:是用四位二进制数表示一位BCD码,用一个字节表示的两位BCD码,即一个字节存放两个十进制数位。
非压缩型BCD码:一个字节可存放一个一位十进制数,其中高4位的内容不做规定(也有部分书籍要求为0,二者均可),低4位二进制表示该位十进制数。例如7的非压缩型BCD码是0000 0111
美国信息交换标准(ASCII码):是一种基于英语中字母字符顺序编码字符的方法。ASCII整数表示具有可打印和不可打印的子集。可打印字符是普通字符,不可打印字符是用于表示键盘键的字符。
程序源码:
BCDL EQU 40H
BCDH EQU 41H
ORG 0000H
MOV R0,#20H
MOV R1,#30H
ACALL FUC
SJMP $
ORG 0050H
FUC:
MOVX A,@R0
MOV B,#10H
DIV AB
ORL B,#30H
MOV BCDL,B
ORL A,R1
MOV BCDH,A
RET
END
扩展题
将寄存器R1中的压缩BCD码拆成两个ASCII码存入片内符号为BCDL,BCDH中,低四位存BCDL,高四位存BCDH。(BCDL,BCDH是字符名称,具体地址自行定义)
程序源码:
BCDL EQU 40H
BCDH EQU 41H
RR1 EQU R1
ORG 0000H
MOV RR1,#28H
;For Testing
LCALL FUC
SJMP $
ORG 0060H
FUC:
MOV A,RR1
MOV B,#10H
DIV AB
ORL B,#30H
MOV BCDL,B
ORL A,#30H
MOV BCDH,A
RET
END
题15
编程实现将外部数据存储器的0100H单元和0020单元中的数据进行互换,然后统计0020H单元内位‘0’的个数且将结果存放在内部RAM的60H中。
程序源码:
RR0 EQU R0
ORG 0000H
MOV RR0,#20H
MOV DPTR,#0100H
MOV 60H,#00H
MOV R6,#08H
CLR C
MOVX A,@DPTR
PUSH ACC
MOVX A,@RR0
MOVX @DPTR,A
POP ACC
MOVX @RR0,A
START:
MOV C,ACC.0
JNC Statistic
SJMP FUC
Statistic:
INC 60H
FUC:
RR A
DJNZ R6,START
SJMP $
END
扩展
编程实现将内部数据存储器的41H单元和40单元中的数据进行互换,然后统计40H单元内位‘1’的个数且将结果存放在内部RAM的60H中。
程序源码:
ORG 0000H
MOV 40H,#19H
MOV 41H,#3DH
;For Testing
MOV 60H,#00H
MOV R7,#8
MOV R0,#40H
CLR C
MOV A,@R0
XCH A,41H
MOV @R0,A
START:
MOV C,ACC.7
JC Statistic
SJMP FUC
Statistic:
INC 60H
FUC:
RL A
DJNZ R7,START
HALT:
SJMP HALT
END
题16
编程实现将内部数据存储器的21H单元中的数据低半字节和内部RAM地址为22H中的低半字节互换后与外部RAM的23H单元中的数据和寄存器R3逻辑异或后进行互换。
解析:一层一层编写代码
程序源码:
Addr EQU 21H
ORG 0000H
LJMP START
ORG 0060H
START:
MOV 21H,#23H
MOV 22H,#18H
MOV 23H,#56H
MOV R3,#74H
;for testing
MOV R0,#22H
MOV A,Addr
XCHD A,@R0
MOV Addr,A
MOV R1,#23H
MOV A,@R1
XRL A,R3
XCH A,Addr
MOV @R1,A
SJMP $
END
注:没有此条指令; XCHD A,Rn
程序中若出现则软件会报错:main.asm(xx): error xxx: INVALID REGISTER
扩展:
编程实现将内部数据存储器的41H单元中的数据高低半字节互换后和外部RAM的41H单元中的数据和寄存器R3逻辑异或后进行互换。
程序源码:
ORG 0000H
MOV R0,#41H
MOV A,@R0
SWAP A
MOV @R0,A
MOV R7,A
MOV R1,#41H
MOVX A,@R1
XRL A,R3
XCH A,R7
MOVX @R1,A
MOV B,R7
MOV @R0,B
SJMP $
END
题17
假设外部RAM地址为40H单元中存有一个单字节有符号数,试编程求其反码和补码,且将其原码、反码和补码存放在内部RAM地址为40H、41H和42H中 。
程序源码:
ORG 0000H
MOV R0,#40H
MOV R1,#40H
MOVX A,@R0
MOV @R1,A
INC R1
JNB ACC.7,RETURN
MOV R1,#42H
MOV C,ACC.7
MOV PSW.5,C
CPL A
PUSH ACC
ADD A,#1
PUSH PSW
MOV C,PSW.5
MOV ACC.7,C
POP PSW
MOV @R1,A
DEC R1
POP B
PUSH PSW
MOV C,F0
MOV B.7,C
POP PSW
MOV @R1,B
SJMP HALT
RETURN:
MOV @R1,A
INC R1
MOV @R1,A
HALT:
SJMP HALT
END
扩展:
假设内部RAM地址为60H单元中存有一个单字节有符号数,试编程求其反码和补码,且将其原码、反码和补码存放在内部RAM地址为50H、51H和52H中 。
程序源码:
ORG 0000H
MOV 60H,#80H
;for testing
MOV R1,#50H
MOV A,60H
MOV @R1,A
INC R1
JNB ACC.7,RETU
MOV R1,#52H
MOV C,ACC.7
MOV PSW.5,C
CPL A
PUSH ACC
ADD A,#1
PUSH PSW
MOV C,F0
MOV ACC.7,C
POP PSW
MOV @R1,A
DEC R1
POP B
PUSH PSW
MOV C,PSW.5
MOV B.7,C
POP PSW
MOV @R1,B
SJMP HALT
RETU:
MOV @R1,A
INC R1
MOV @R1,A
HALT:
SJMP HALT
END
仿真结果:
题18
设变量x以补码形式存放在外部RAM的20H中,变量y的地址为内部RAM60H,且变量y与x的关系如下图,请编程实现下图所示功能。
程序源码:
y EQU 60H
x EQU 20H
ORG 0000H
MOV R0,#x
MOV R1,#y
MOVX A,@R0
JZ ACCZERO
MOV C,ACC.7
MOV 7FH,C
JB 7FH,SZERO
MOV y,A
SJMP HALT
ACCZERO:
MOV y,#09H
SJMP HALT
SZERO:;A<0
ADD A,#14H
MOV y,A
HALT:
SJMP HALT
END
扩展:
设变量x以补码形式存放在内部RAM的60H中,变量y的地址为外部RAM0100H,且变量y与x的关系如下图,请编程实现下图所示功能,且将计算出的y值屏蔽其第3位和第5位后存于外部RAM地址为0101H中
程序原码:
yend EQU 0101H
x EQU 60H
ORG 0000H
MOV R0,#x
MOV DPTR,#yend
MOV R5,#00H
MOV A,@R0
JZ ACCZERO
MOV C,ACC.7
MOV 7FH,C
JB 7FH,SZERO
MOV R5,A
SJMP RETU
ACCZERO:
MOV R5,#09H
SJMP RETU
SZERO:;
ADD A,#14H
MOV R5,A
RETU:
CLR A
XCH A,R5
ANL A,#0D7H
MOVX @DPTR,A
HALT:
SJMP HALT
END
题19
设有100个单字节无符号数,连续存储在内部RAM的M单元开始的数据存储器中,且总和不超过16位二进制数,并将相加结果存放在N单元和N+1单元(低八位存放在N单元)
程序源码:
N EQU 20H
M EQU 23H
ORG 2020H
MOV A,#00H
CLR C
MOV R7,#100
MOV 20H,#00H
MOV R0,#M
MOV R1,#N
LOOP:
ADDC A,@R1
JNC L1
INC 20H
L1:
INC R1
DJNZ R7,LOOP
MOV @R0,A
HALT:
SJMP HALT
END
扩展:
设有100个单字节无符号数,连续存储在外部RAM的M单元开始的数据存储器中,且总和不超过16位二进制数,并将相加结果存放在内部RAMN单元和N+1单元(低八位存放在N单元)
程序源码:
N EQU 20H
M EQU 23H
ORG 002DH
MOV A,#00H
CLR C
MOV R7,#100
MOV 20H,#00H
MOV R0,#M
MOV R1,#N
MOV B,#00H
LOOP:
MOVX A,@R1
ADDC A,B
JNC L1
INC 20H
L1:
INC R1
XCH A,B
DJNZ R7,LOOP
MOV @R0,A
HALT:
SJMP HALT
END
题20
为一串7位ASCII码数据的D7位加上奇校验,设数据存放在片内RAM的40H起始单元,数据长度在30H单元。
解析:
奇/偶校验(Parity Check)是数据传送时采用的一种校正数据错误的一种方式,根据被传输的一组二进制代码的数位中“1”的个数是奇数或偶数来进行校验。
奇校验:在传送每一个字节的时候另外附加一位作为校验位,校验位在数据位后面,当实际数据中“1”的个数为偶数的时候,这个校验位就是“1”,否则这个校验位就是“0”,这样就可以保证传送数据满足奇校验的要求。在接收方收到数据时,将按照奇校验的要求检测数据中“1”的个数,如果是奇数,表示传送正确,否则表示传送错误。
偶校验: 当实际数据中“1”的个数为偶数的时候,这个校验位就是“0”,否则这个校验位就是“1”,这样就可以保证传送数据满足偶校验的要求。在接收方收到数据时,将按照偶校验的要求检测数据中“1”的个数,如果是偶数个“1”,表示传送正确,否则表示传送错误。
例如:如下图
程序源码:
ORG 0000H
MOV 30H,#10
MOV 40H,#65H
MOV 41H,#13H
;for testing
MOV R0,#40H
LOOP:
MOV A,@R0
ORL A,#80H
JNB P,PASS
MOV @R0,A
PASS:
INC R0
DJNZ 30H,LOOP
HALT:
SJMP HALT
END
扩展:
为一串7位ASCII码数据的D0位加上偶校验,设数据存放在片外RAM的0100H起始单元,数据长度在片外RAM中的30H单元。
程序源码:
ORG 0000H
MOV R0,#30H
MOV DPTR,#0100H
MOVX A,@R0
MOV B,A
LOOP:
MOVX A,@DPTR
ORL A,#01H
JB P,PASS
MOVX @DPTR,A
PASS:
INC DPTR
DJNZ B,LOOP
HALT:
SJMP HALT
END