资源描述
\
实验一 内存操作
1. 实验目的
① 掌握数据传送指令;
② 掌握各种数据传送指令的寻址方式;
③ 熟练运用keil 环境对汇编程序进行调试;
④ 掌握数据传送、复制等程序的设计与调试方法。
2. 预习要求
① 理解数据传送指令和循环指令的使用;
② 理解如何对内部寄存器、内部RAM、外部XRAM(外部数据存储器)的读写;
③ 理解各种寻址方式,尤其是较为抽象的变址寻址及相对寻址的方式;
④ 认真预习本实验内容,自行编写程序,填写实验报告。
3. 实验设备
计算机 1台;
4.基础型实验内容:
1. 下列程序的功能是给外部XRAM 8000H~80FFH的256个单元的内容赋值,赋值的内容取决于程序中A的赋值。在Keil环境运行该程序,并观察寄存器及内存单元的变化。
ORG 0000H
START EQU 8000H;
MAIN: MOV DPTR,#START; ;起始地址
MOV R0,#0H; ;设置256字节计数值
MOV A,#1H;
Loop: MOVX @DPTR,A;
INC DPTR; ;指向下一个地址
DJNZ R0,Loop; ;计数值减1
NOP;
SJMP $;
END
寄存器A为1H,DPTR递增到8100H,奇偶校验位由于A的内容是1H,所以p也是1.
2. 下列程序将外部XRAM 3000H起始的256个字节存储块移动到外部XRAM 4000H起始的256个字节存储块,在Keil环境运行如下程序,观察寄存器及存储单元的变化。
ORG 0000H
MOV DPTR,#3000H
MOV A,#01H
MOV R5,#0H
LOOP: MOVX @DPTR,A
INC DPTR
DJNZ R5,LOOP
MOV R0,#30H
MOV R1,#00H
MOV R2,#40H
MOV R3,#00H
MOV R7,#0H
LOOP1: MOV DPH,R0
MOV DPL,R1
MOVX A,@DPTR
MOV DPH,R2
MOV DPL,R3
MOVX @DPTR,A
INC R1
INC R3
DJNZ R7,LOOP1
SJMP $
END
实现了将3000H开始的256个单元的内容复制到以4000H开头的外部RAM存储单元中。
R0的值为30H;R2的值变为40H;寄存器A中赋值为1H,对栈指针sp初始化为07H,其最大值亦为07H,DPTR中最后递增到40ffH,psw中只有奇偶校验位p是1H
3在Keil环境运行如下程序,观察寄存器及内存单元的变化,将变化结果注释于右侧,并说明程序完成什么功能?将程序中MOV A,@R0改成MOVX A,@R0,将MOV @R1,A改成MOVX @R1,A,运行如下程序,观察寄存器及相应地址RAM、XRAM地址单元存储内容的变化。
1.
ORG 0000H;程序从000H开始
MOV R0,#30H;
MOV R1,#50H
MOV R2,#20H
L1: MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R2,L1
SJMP $
END
R0的值递增到50H,R1的值递增到70H,A中的值是4FH中的值,即FFH(程序运行前自己设定的)
该程序将内部RAM 30H开始的连续20H个存储单元中的内容复制到内部RAM 50H开始的连续20H个存储单元中。其中30H到4FH中的值在程序运行前自定义。
2. 将程序中MOV A,@R0改成MOVX A,@R0,将MOV @R1,A改成MOVX @R1,A
ORG 0000H
MOV R0,#30H
MOV R1,#50H
MOV R2,#20H
L1: MOVX A,@R0
MOVX @R1,A
INC R0
INC R1
DJNZ R2,L1
SJMP $
END
寄存器A中的数值没有发生过任何变化,R0和R1同未改变前一样,一直递增到50H和70H
虽然设定了外部RAM 30H到4FH中的值,但是并没有复制到50H到6FH存储单元中。
原因是初始化后P口都为#FFH,而使用MOVX A,@Ri要求P2口为#00H,所以只要在程序前加MOV P2,#00H就能实现和原来一样的功能了
5.设计型实验
① 在keil环境下,修改内部RAM 30H ~3FH的内容分别为#00H ~#0FH,设计程序实现将内部RAM 30H-3FH单元的内容复制到40H-4FH中。
ORG 000H;
MOV R2,#10H;
MOV A,#0H;
MOV R1,#30H;
MOV R0,#40H;
LOOP: MOV @R1,A;
INC R1;
INC A;
DJNZ R2,LOOP;
MOV R1,#30H;
MOV R2,#10H;
LOOP2:MOV A,@R1;
MOV @R0,A;
INC R1;
INC R0;
DJNZ R2,LOOP2;
SJMP $;
END
② 在keil环境下,修改内部RAM 30H ~3FH的内容分别为#00H ~#0FH,设计程序实现将内部RAM 30H~3FH单元的内容复制到片外1030H~103FH中。
ORG 000H;
MOV R2,#10H;
MOV A,#0H;
MOV R1,#30H;
MOV DPTR,#1030H;
LOOP: MOV @R1,A;
INC R1;
INC A;
DJNZ R2,LOOP;
MOV R1,#30H;
MOV R2,#10H;
LOOP2:MOV A,@R1;
MOVX @DPTR,A;
INC R1;
INC DPTR;
DJNZ R2,LOOP2;
SJMP $;
END
③ 设计程序将外部64KB的XRAM高低地址存储内容互换;如0000H与0FFFFH,0001H与0FFFEH,0002H与0FFFDH,…….互换;互换数据个数为256。
ORG 000H;
MOV DPTR,#0FFFFH;
MOV R1,DPL ;保存当然DPTR低位
loop:
MOV DPL,R1;
MOVX A,@DPTR;
MOV R3,A ;保存当前DPTR的内容
MOV R0,DPH ;保存当然DPTR高位
MOV A,DPH;
CPL A ;求得当前DPTR高位的反码
MOV DPH,A;
MOV A,R1;
CPL A ;求得当前DPTR低位的反码
MOV DPL,A ;求得当前DPTR反码
MOVX A,@DPTR;
MOV R4,A ;保存当前DPTR对称码(反码)的内容
MOV A,R3;
MOVX @DPTR,A ;将当前DPTR(原码)的内容存入对称码中
MOV DPH,R0;
MOV DPL,R1 ;还原DPTR
MOV A,R4;
MOVX @DPTR,A ;将对称码的内容存入当前DPTR(原码)
DEC R1;
CJNE R1,#0FFH,LOOP;
SJMP $;
END
运行前:
运行后:
6. 综合型实验
a) 设计程序实现将外部XRAM 0000H起始的512个字节数据传送到外部XRAM 2000H起始的512个存储单元中。
ORG 0000H;
MOV R3,#0H;
MOV DPTR,#0000H;
LOOP:
MOVX A,@DPTR;
MOV R0,DPL;
MOV DPH,#20H;
MOVX @DPTR,A;
INC R0;
MOV DPL,R0;
MOV DPH,#0H;
DJNZ R3,LOOP;
SJMP $;
END
X:0H至X:0FFH的值是自定义的;运行程序后复制到X:2000H至X:20FFH;
b) 若源块地址和目标块地址有重叠,程序该如何设计(用地址减1方法移动块)?假设源块地址2000H,目标块地址2050H,移动块长度80H;试设计程序实现该功能。
思路:先将由源块地址起始的数据块保存到非目标块地址中(防止覆盖目标地址),然后再复制到目标块地址;
ORG 0000H;
MOV DPTR,#2000H;
MOV R3,#80H;
LOOP:
MOVX A,@DPTR;
MOV R0,DPH;
MOV R1,DPL;
MOV DPH,#30H;
MOVX @DPTR,A;
MOV DPH,R0;
INC R1;
MOV DPL,R1;
DJNZ R3,LOOP;本循环实现将x:2000H开始的80个单元中的内容复制到x:3000H开始的80个单元中去
MOV DPTR,#3000H;
MOV R3,#80H;
MOV R4,#50H;
LOOP2:
MOVX A,@DPTR;
MOV R2,A;
MOV R0,DPH;
MOV R1,DPL;
MOV A,R4;
MOV DPH,#20H;
MOV DPL,A;
MOV A,R2;
MOVX @DPTR,A;
INC R4;
MOV DPH,R0;
INC R1;
MOV DPL,R1;
DJNZ R3,LOOP2;本循环实现将x:3000H开始的80个单元中的内容复制到x:2050H开始的80个单元中去
SJMP $;
END
实验二 数制及代码转换
1. 实验目的
① 了解微机系统中的数制与代码表示方法;
② 掌握计算机中使用的各种代码转换方法;
③ 掌握实现分支、循环的指令及其程序的编写方法;
2. 预习要求
① 理解十进制数、十六进制数的数制表示方法;
② 理解BCD码、ASCII码编码方式;
③ 如何实现十六进制数与BCD码之间的转换;
④ 如何实现ASCII码与BCD码之间的转换。
3. 实验设备
计算机 1台。
4. 基础型实验内容
① 以下程序完成单字节的ASCII码到十六进制数转换,完成空白处程序填写,并在Keil环境运行程序,观察寄存器及相应地址内存单元内容的变化。
RESULT EQU 30H
ORG 0000H
MOV A,#41H ;“A”的ASCII码
CLR C
SUBB A,#37H ; 转换为十六进制值A
MOV RESULT,A
LJMP $
END
② 以下程序完成单字节的BCD码到十六进制数转换,,在Keil环境运行程序,观察寄存器及相应地址内存单元内容的变化。
RESULT EQU 30H
ORG 0000H
MOV A,#23H
MOV R0,A
ANL A,#0F0H
SWAP A
MOV B,#0AH
MUL AB
MOV RESULT,A ;转换高位
MOV A,R0
MOV B,#0FH
ANL A,B;
ADD A,RESULT
MOV RESULT,A ;转换低位
SJMP $
END
③ 以下程序将单字节十六进制数A的值转换为十进制数,存放在30H~32H中,完成空白处程序填写,并在Keil环境运行程序,观察寄存器及相应地址内存单元内容的变化。
RESULT EQU 30H
ORG 0000H
MOV A,#7BH
MOV B,#100
DIV AB
MOV RESULT,A ;除以100得百位数
MOV A,B
MOV B,#10
DIV AB
MOV RESULT+1,A ;除以10得十位数
MOV RESULT+2,B ;余数为个位数
SJMP $
END
5. 设计型实验内容
① 将30H、31H单元中的十六进制数,转换成ASCII码,存放到40H开始的4个单元中。
ORG 0000H;
MOV R2,30H;
MOV R3,31H;
MOV R0,#40H;
MAIN:
MOV A,R2;
ANL A,#0F0H;
SWAP A;
ADD A,#90H;
DA A;
ADDC A,#40H;
DA A;
MOV @R0,A ;将31H中的高位转化成ASCII码
INC R0;
MOV A,R2;
ANL A,#0FH;
ADD A,#90H;
DA A;
ADDC A,#40H;
DA A;
MOV @R0,A ;将30H中的低位转化成ASCII码
INC R0;
MOV A,R3;
ANL A,#0F0H;
SWAP A;
ADD A,#90H;
DA A;
ADDC A,#40H;
DA A;
MOV @R0,A ;将30H中的高位转化成ASCII码
INC R0;
MOV A,R3;
ANL A,#0FH;
ADD A,#90H;
DA A;
ADDC A,#40H;
DA A;
MOV @R0,A ;将31H中的低位转化成ASCII码
INC R0;
SJMP $;
END
② 单字节十六进制数转换为十进制数的程序设计。设单字节十六进制数存放在内部RAM 30H 中,结果要求存放到内部RAM 40H-41H中。
本题应该是40H-42H,因为该十六进制数完全有可能超过100
RESULT EQU 40H;
ORG 0000H;
MOV R0,#30H;
MOV A,@R0;
MOV B,#100
DIV AB
MOV RESULT,A ;除以100得百位数
MOV A,B
MOV B,#10
DIV AB
MOV RESULT+1H,A ;除以10得十位数
MOV RESULT+2H,B ;余数为个位数
SJMP $
END
③ 单字节压缩BCD码数转换成十六进制数的程序设计。设压缩BCD码数存放在内部RAM30H中,结果要求存放在内部RAM40H中。
RESULT EQU 40H; ;设置存放地址
ORG 0000H;
MOV R1,#30H;
MOV A,@R1;
ANL A,#0F0H ;取高4位
SWAP A;
MOV B,#0AH;
MUL AB ;高位乘以10
MOV RESULT,A ;转换高位
MOV A,@R1;
MOV B,#0FH ;取低4位
ANL A,B;
ADD A,RESULT;
MOV RESULT,A ;转换低位
SJMP $;
END
6. 综合实验
① 多字节十六进制数转换为十进制数的程序设计。设多字节十六进制数存放在内部RAM 30H 开始的单元中,要求结果存放在内部RAM 40H开始的单元中。
ORG 0000H;
MOV R1,#40H ;存放单元
MOV R0,#30H ;起始存储单元
MOV R2,#9H ;设置要转化的单元数,即循环次数
LOOP:
MOV A,@R0;
MOV B,#100;
DIV AB;
MOV @R1,A ;除以100得百位数
INC R1;
MOV A,B
MOV B,#10;
DIV AB
MOV @R1,A ;除以10得十位数
INC R1;
MOV @R1,B ;余数为个位
INC R1;
INC R0;
DJNZ R2,LOOP;
SJMP $;
END
注:由于内部RAM 30H与内部RAM 40H之间只有16个单元,即循环的次数最好不要超过16次,否则数据块发生重叠,如果非要进行16次以上操作,那么可以先将转化好的十进制数存放到其他内存中,最后再统一复制到40H开始的内存中,此处不再列出程序。
② 多字节压缩BCD码数转换成十六进制数的程序设计。设压缩BCD码数存放在内部RAM30H开始的单元中,要求结果存放在内部RAM 40H开始的单元中。
ORG 0000H;
MOV R0,#40H; ;设置存放地址
MOV R1,#30H;
MOV R2,#9H;
LOOP:
MOV A,@R1;
ANL A,#0F0H ;取高4位
SWAP A;
MOV B,#0AH;
MUL AB ;高位乘以10
MOV @R0,A ;转换高位
MOV A,@R1;
MOV B,#0FH ;取低4位
ANL A,B;
ADD A,@R0;
MOV @R0,A ;转换低位
INC R0;
INC R1;
DJNZ R2,LOOP;
SJMP $;
END
注:由于内部RAM 30H与内部RAM 40H之间只有16个单元,即循环的次数最好不要超过16次,否则数据块发生重叠,如果非要进行16次以上操作,那么可以先将转化好的十进制数存放到其他内存中,最后再统一复制到40H开始的内存中,此处不再列出程序。
实验三 算术运算
1. 实验目的
① 掌握算术运算类、逻辑运算类指令的使用方法;
② 掌握BCD码、补码数制表示方法;
③ 掌握运算程序及循环程序的编写和调试方法。
2. 预习要求
① 理解8051单片机的算术运算指令;
② 理解补码表示数值的方法;
③ 理解压缩、非压缩BCD码表示数值的方法;
④ 如何实现多位数的BCD码加、乘、除运算;
⑤ 如何实现多位数的BCD码减法运算;
⑥ 预习本实验内容,以及相关课程内容。
3. 实验设备
计算机 1台。
4. 基础型实验内容
① 以下程序完成单字节的BCD码加法功能,完成空白处程序填写,并在Keil环境运行程序,观察寄存器及相应地址内存单元内容的变化。
RESULT EQU 30H
ORG 0000H
MOV A,#99H
MOV B,#99H
ADD A , B
DA A ; BCD码相加并得到BCD码结果
MOV RESULT,A
MOV A,#00H
ADDC A,#00H
MOV RESULT+1,A ;高位处理
SJMP $
END
② 下列程序完成多字节BCD码加法运算。内部RAM 30H开始的4字节长的BCD码和外部XRAM 1000H开始的4字节长的BCD码相加,结果放在外部XRAM 1100H开始的单元中(从低字节到高字节),在Keil环境运行程序,观察寄存器及相应地址内存单元内容的变化。
ORG 0000H
CLR C
MOV R5,#04H
MOV R0,#30H
MOV R1,#10H
MOV R2,#00H
MOV R3,#11H
MOV R4,#00H
L1:MOV DPH,R1
MOV DPL,R2
MOVX A,@DPTR
ADDC A, @R0
DA A ;十进制调整
MOV DPH,R3
MOV DPL,R4
MOVX @DPTR,A
INC R2
INC R4
INC R0
L2:DJNZ R5, L1
JNC L3
MOV DPTR,#1104H ;有进位则结果的第五个字节置1
MOV A,#01H
MOVX @DPTR,A
L3:NOP
SJMP $
END
5. 设计型实验内容
① 设计程序,实现任意字节(设字节数为n)压缩BCD码的相加。加数分别存放在外部RAM 1000H和内部RAM 30H开始的单元中,结果保存到内部RAM 40H开始的单元中。
因为是任意字节,所以相加的结果不能直接放在内部40H开始的单元中,因为字节数可能超过10H个;所以需要设置临时存放和的地址
ORG 0000H;
CLR C;
MOV R5,#04H ;自定义需要参加运算的字节数
MOV A,R5;
MOV R6,A ;保存参加运算的字节数
MOV R0,#30H ;存放加数的片内RAM起始地址30H
MOV R1,#10H;
MOV R2,#00H ;存放加数的片外RAM起始地址1000H
MOV R3,#21H;
MOV R4,#00H ;临时保存和的片外RAM起始地址2100H
L1:MOV DPH,R1;
MOV DPL,R2;
MOVX A,@DPTR;
ADDC A,@R0;
DA A ;十进制调整
MOV DPH,R3;
MOV DPL,R4;
MOVX @DPTR,A;
INC R2;
INC R4;
INC R0;
L2:DJNZ R5,L1;
JNC L3;
MOV DPH,R3;
MOV DPL,R4 ;有进位则结果的下一个字节置1
MOV A,#01H;
MOVX @DPTR,A;
L3:NOP;
MOV DPH,R3;
MOV DPL,R4;
MOVX A,@DPTR;
CJNE A,#01H,L4 ;判断是否做加法后有进位,有则使R6加1
INC R6;
MOV R0,#40H ;本语句块实现将临时存放单元中的和复制到内部RAM中以40H起始的存储单元中
MOV R1,#00H;
MOV R2,#21H;
L4: MOV DPH,R2;
MOV DPL,R1;
MOVX A,@DPTR;
MOV @R0,A;
INC R0;
INC R1;
CJNE R1,#00H,L5;
INC R2 ;R1变成00H之后,R2加1
L5: DJNZ R6,L4;
SJMP $;
END
② 设计程序,实现多字节(设字节数为n)十六进制无符号数的减法。被减数和减数分别存放在外部RAM 1000H和内部RAM 30H开始的单元中,结果保存到内部RAM 40H开始的单元中。
ORG 0000H;
MOV R4,#00H ;被减数低位地址
MOV R2,#10H ;被减数高位地址
MOV R1,#30H ;减数地址
MOV R3,#4H ;设置字节数
MOV R0,#40H ;设置存放地址
LOOP: MOV DPL,R4 ;本循环实现字节的逐个相减的过程
MOV DPH,R2;
MOVX A,@DPTR;
SUBB A,@R1;
MOV @R0,A;
INC R0;
INC R4;
INC R1;
CJNE R4,#0H,L ;如果R4增加到0H,则高位加1
INC R2;
L: DJNZ R3,LOOP;
SJMP $;
END
③ 在内部RAM 30H单元开始,存放着一串带符号数据(负数用补码表示),数据长度在10H中(设数据长度小于等于16);编程分别求其中正数之和与负数之和,并存入内部RAM的2CH与2EH开始的2个单元中,记录程序运行结果。
例如:内部RAM的30H-35H存放-1,5,-2,19,-8,对应的补码分别为0FFH,5H,0FEH,13H,0F8H,则正、负数的和分别为24、-11,对应的补码分别为18H,0F5H。
ORG 0000H;
MOV R2,#10H;
MOV R0,#30H;
MOV R3,#00H;
MOV R4,#00H;
MAIN:MOV A,@R0;
JB ACC.7,SUBBB;
SJMP ADDDD;
L: INC R0;
DJNZ R2,MAIN;
SJMP EXIT;
SUBBB:CLR ACC.7 ;负数做正数处理
MOV B,A;
MOV A,R3;
CLR ACC.7;
MOV R3,A;
MOV A,B;
ADD A,R3;
MOV R7,A;
JNB CY,NEXT1;
MOV A,#01H;
ADD A,R6;
MOV R6,A ;R6中存放高8位
MOV A,R7;
NEXT1:
MOV R3,A ;R3中存放低8位
CLR CY;
SJMP L;
ADDDD:
ADD A,R4;
JNB CY,NEXT2;
INC R1 ;R1中存放高8位
NEXT2:MOV R4,A ;R4中存放低8位
CLR CY;
SJMP L;
EXIT: MOV 2CH,R1;
MOV 2DH,R4;
MOV 2EH,R6;
MOV 2FH,R3;
SJMP $;
END
6. 综合实验
① 设计程序,实现十六进制无符号数双字节乘单字节,结果存于内部RAM的40H开始的三个单元中,使用单步、断点方式调试程序,查看结果。
(调试数据:35A6H*56H)
ORG 0000H;
MULMST:
MOV R0,#40H ;设置存放地址
MOV A,R3;
MOV B,R5;
MUL AB ;R3*R5=BA
MOV @R0,A ;R3R5L送40H单元
MOV R7,B ; R3R5H暂存R7
MOV A,R2;
MOV B,R5;
MUL AB ;R2*R5=BA
ADD A,R7 ; R3R5H+R2R5L,形成标志位Cy
INC R0;
MOV @R0,A ; R3R5H+R2R5L结果存放到41H单元
CLR A;
ADDC A,B ; R2R5H+Cy
INC R0;
MOV @R0,A ; R2R5H+Cy存放到42H
SJMP $;
END;
最终结果:
单点调试:
断点调试:
第一次乘法:
第二次乘法:
得到最高位:
全部存入对应地址:
② 设计一个实现十六进制无符号数双字节乘双字节的通用程序。
ORG 0000H;
MOV R0,#40H;
MUL1: MOV A,R3;
MOV B,R5;
MUL AB;
MOV @R0,A;
MOV R7,B;
MOV A,R2;
MOV B,R5;
MUL AB;
ADD A,R7;
MOV R7,A;
CLR A;
ADDC A,B;
MOV R6,A;
MOV A,R3;
MOV B,R4;
MUL AB;
ADD A,R7;
INC R0;
MOV @R0,A;
MOV A,R6;
ADDC A,B;
MOV R7,A;
MOV F0,C;
MOV A,R2;
MOV B,R4;
MUL AB;
ADD A,R7;
INC R0;
MOV @R0,A;
CLR A;
MOV ACC.0,C;
MOV C,F0;
ADDC A,B;
INC R0;
MOV @R0,A;
SJMP $;
END
最终结果:
实验四 比较和查表
1. 实验目的
① 掌握比较指令的使用及循环程序的编写方法;
② 掌握字符查找的思路和算法;
③ 理解并能运用查表和散转指令。
2. 预习要求
① 理解掌握比较程序的设计思路;
② 理解多分支结构程序的编程方法;
③ 预习本节实验内容,编写程序及实验预习报告。
3. 实验设备
计算机 1台。
4. 基础型实验内容
① 以下程序完成共阴数码管数值显示译码的功能,在Keil环境运行程序,观察寄存器及相应地址内存单元内容的变化,将变化结果注释于右侧。
ORG 0000H
MOV R2,#10H
MOV DPTR,#TBL
L0: MOV A,#00H
MOVC A,@A+DPTR
INC DPTR
DJNZ R2,L0
SJMP $
TBL: DB 3FH,06H,5BH,4FH,66H,6DH
DB 7DH,07H,7FH,6FH,77H,7CH
DB 58H,5EH,79H,71H,00H,40H
END
② 以下程序用PC指针做基址实现一个两位十六进制数到ASCII码的转换,转换源数值存放在R2中,转换结果低位存于R2,高位存于
展开阅读全文