25.设A=40H,R1=23H,(40)=05H。执行下列两条指令后,累加器A和R1以及内部RAM中40H单元的内容各为何值? XCH A,R1;(A)=23H,(R1)=40H XCHD A,@R1;(A)=25H,(40H)=03H
26.指出下列程序段的每条指令的源操作数是什么寻址方式,并写出每步运算的结果。(相关单元的内容)设程序存储器(1050H)=5AH. 1)MOV A,#0FH 2)MOV 30H,#0F0H 3)MOV R2,A 4)MOV R1,#30H 5)MOV A,@R1 6)MOV DPTR,#1000H 7)MOV A,#50H 8)MOVC A,@ A+ DPTR 9)JMP @A+DPTR 10)CLR C 11)MOV 20H,C ;立即寻址方式,A=0FH ;立即寻址,(30H)=0F0H ; 寄存器寻址方式,R2=A ;立即寻址,执行后R1=30H ;寄存器间接寻址,A=(30H) ;立即寻址,DPTR=1000H ;立即寻址,A=50H ;寄存器间接寻址,A=(1050H)=5AH ;寄存器间接寻址,PC=A+DPTR ;位寻址,C=0 ; 寄存器寻址方式,(20H)=C 三、计算编程题
1.已知内部RAM的BLOCK单元开始有一无符号数据块,块长在LEN单元,请编出数据块中各数累加和并存入SUM单元的框图和程序。
(1)先判断后处理 (2)先处理后判断
[例4-3] 从BLOCK单元开始存放一组无符号数,一般称为一个数据块。数据块长度放在LEN单元,编写一个求和程序,将和存入SUM单元,假设和不超过8位二进制数。
在置初值时,将数据块长度置入一个工作寄存器,将数据块首地址送入另一个工作寄存器,一般称它为数据块地址指针。每做一次加法之后,修改地址指针,以便取出下一个数来相加,并且使计数器减1。到计数器减到0时,求和结束,把和存入SUM即可。 参考程序:各单元的地址是任意的。
ORG 1000H LEN DATA 20H SUM DATA 21H BLOCK DATA 22H CLR A ;清累加器 MOV LEN R2 , ;数据块长度送R2 MOV # BLOCK R1 , ;数据块首址送Rl
ADD @R1 LOOP: A , ;循环做加法
INC R1 ;修改地址指针 DJNZ LOOP R2 , ;修改计数器并判断 MOV A SUM , ;存和 SJMP $ END
2.试编制程序求2个无符号数据块中的最大值,数据块的首地址分别为60H和70H,每个数据块的第一个字节都存放数据块的长度,结果存入5FH单元。
[例4-6] 内部RAM20H单元开始存放8个无符号8位二进制数,找出其中的最大数。极值查找操作的主要内容是进行数值大小的比较。假定在比较过程中,以A存放大数,与之逐个比较的另一个数放在2AH单元中。比较结束后,把查找到的最大数送2BH单元中。程序流程如图所示。
参考程序如下: MOV # 20H R0 , ;数据区首地址 MOV # 08H R7 , ;数据区长度 MOV @R0 A , ;读第一个数 DEC R7
INC R0 LOOP:
MOV @R0 2AH , ;读下一个数 CJNE A ,2AH , CHK ;数值比较
JNC LOOP1 CHK: ;A值大转移
MOV @R0 A , ;大数送A
LOOP LOOP1: DJNZ R7 , ;继续
MOV A 2BH , ;极值送2BH单元
AJMP HERE HERE: ;停止
3.将内部的数据存储器某一单元中的一个字节的16进制数转换成2位ASCII码,结果存在内部数据存储器的两个连续单元中。(注,30H~30H为0~9,41H~46H为A~F)
[例4-5] 在内部RAM的hex单元中存有2位十六进制数,试将其转换为ASCII码,并存放于asc和asc+1两个单元中。
主程序(MAIN): MOV # 3FH SP ,
PUSH hex MAIN: ;十六进制数进栈
ACALL HASC ;调用转换子程序
;第一位转换结果送asc单
POP asc
元
MOV hex A , ;再取原十六进制数 SWAP A ;高低半字节交换 PUSH ACC ;交换后的十六进制数进栈 ACALL HASC
;第二位转换结果送asc+l
POP asc+l
单元
子程序(HASC):
DEC SP HASC: ;跨过断点保护内容
DEC SP POP ACC ;弹出转换数据 ANL # 0FH A , ;屏蔽高位 ADD # 7 A , ;修改变址寄存器内容 MOVC @A+PC A , ;查表 PUSH ACC ;查表结果进栈
INC SP ;修改堆栈指针回到断点保
护内容
INC SP RET SP ASCTAB: DB “0,1,2,3,4,5,6,7” ;ASCII码表 DB “8,9,A,B,C,D,E,F”
4.8031对外部ROM和RAM的连接如下图,8031的地址采用全译码方式,片选选P2.7用于控制二-四译码器工作,片选线P2.6和P2.5参加译码,且无悬空的片选线,因此存储器所有的地址都是唯一的,地址无重叠,地址译码器Y0 Y1 Y2的输出端分别和1 2 3 存储器相连,请表明存储芯片1 2 3 的基本地址范围。 1#2764: 0000H~1FFFH 8KB;2#6264 :2000H~3FFFH 8KB;3#6264:4000H~5FFFH 8KB
P2.72764(1)000000P2.6000011P2.5001100P2.4…. P0地址范围0000H---1FFFH2000H---3FFFH4000H---5FFFH0 …. 01 …. 10 …. 01 …. 10 …. 01 …. 12764(2)6264
5.用8255芯片扩展单片机的I/O口,8255的A口用作输入,A口的每一位接一个开关。用B口作为输出,输出的每一位接一个发光二极管。现要求某个开关接1时,相应位上的发光二极管就亮(输出低电平0)。试编写相应的程序。设8255的A口地址为70H,B口地址为71H,C口地址为72H,控制口地址为73H。
8255与8031的连接按常规进行(根据给定的地址)。根据题意,只需采用无条件传送方式。初始化时,规定8255 A口为输入方式,B口为输出方式,故工作方式控制字为10010000,即90H。读入A口数据后,取反并从B口输出,即可完成所需功能,程序如下:
MOV R0,#73H ;控制字寄存器地址 MOV A,#90H ;控制字 MOVX @R0,A ;输出控制字 MOV R0,#70H ;A口地址 MOVX A,@R0 ;从A口读入 CPL A INC R0 ;B口地址 MOVX @R0,A ;从B口输出 SJMP $ END
如图有6个LED采用共阴极连接,79H-7EH分别存放6位显示器数据(0-5),8255的A口接LED显示器位控,8255的B口接LED显示器端控。为了存放显示的数字或字符,通常在内部RAM中设置显示缓冲区,其单元个数与LED显示器位数相同。假定本例中6个显示器的缓冲单元是79H~7EH。
假定位控口地址0103H,段控口地址010lH。以R0存放当前位控值,DL为延时子程序。程序清单:
MOV # 79H DIR: R0 , ;建立显示缓冲区首址
MOV # 0lH R3 , ;从右数第一位显示器开
始
MOV R3 A , ;位控码初值
MOV # 0103H LDO: DPTR , ;位控口地址
MOVX A @DPTR , ;输出位控码 MOV # 010lH DPTR, ;得段控口地址 MOV @R0 A , ;取出显示数据
ADD # 0DH DIR0: A ,
MOVC @A+PC A , ;查表取字形代码
MOVX A DIR1: @DPTR , ;输出段控码
ACALL DL ;延时,维持点亮 INC R0 ;转向下一缓冲单元 MOV R3 A , JB LDl ACC.5 , ;判是否到最高位,到则
返回
RL A ;不到,向显示器高位移
位
MOV A R3 , ;位控码送R3保存 AJMP LD0 ;继续扫描
RET LD1:
DB C0H DSEG: ;字形代码表
DB F9H DB A4H
6 如图8031和8253的一种连接方式CS与P2.7相连,8031选用12MHz晶振,ALE,WR和RD通过图中的逻辑组合后输出频率为2MHz的脉冲信号,作为8253计数器2时钟输入信号,把计数器2设置成方式3工作状态,编写输出40kHz方波的初始化程序。(教材P193) 解:计数初值为2MHz/40kHz=50,则实现8253的OUT2输出40kHz方波信号的程序如下:
MOV DPTR,#7FFFH ;指向控制寄存器 MOV A,#0B6H ;设置计数器2输出方波 MOVX @DPTR,A ;控制字送入控制寄存器 MOV DPTR,#7FFEH ;指向计数器 MOV A,#32H ;50分频计数器值为0032H MOVX @DPTR,A 先写入低8位值 CLR A 高8位地址为00H MOVX @DPTR,A 后写入高8位值