学号:0740303104
姓名:雷凤
循环程序设计实验报告
一、实验目的:
1、了解和掌握比较循环程序的组成部分,重复控制指令的功能、作用和方法。
2、学会循环程序设计的方法。
3、学习汇编语言输出输入语句的设计。
二、实验要求:
1、具体了解和掌握循环程序的组成部分,重复控制指令的使用和在使用时应注意的问题
2、学习循环序设计的一般方法。
三、实验内容
1、实验任务
设有N个学生的某科成绩(百分制),已按学号的次序存放在以STUD为首址的字单元数组中,现要求按成绩的高低记入名次,并把名次填入成绩所在的字单元的高字节中。
字单元的格式为
2、实验的原理
这个实验要用循环的嵌套,内外循环都循环6次,刚开始时将所有的名次都置1,外循环从第一个成绩开始依次与每一个学生(包括自己)的成绩比较大小,要是小于,相应的名次就加1,再将第二个成绩与所有的分数依次比较大小,一直循环6次,就能得出名次排序了,将相应的名次分别保存在dl低字节中,也便于输出名次。
3、程序设计流程图
四、实验步骤
1、编辑源程序,建立一个以后缀为 .ASM的文件.
DATAS SEGMENT
;此处输入数据段代码
STUD DW 78,65,89,90,58,99
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
LEA BX,STUD
MOV CX,6 ;设置计数器
LOP1:
PUSH CX
MOV dl,1 ;dl用来存放名次
MOV AL,[BX] ;BX的内容送给AL
MOV CX,6
LEA SI,STUD ;取偏移地址
LOP2:
CMP AL,[SI] ;比较大小
JL LOP3 ;小于就转
JMP A ;LOOP LOP
LOP3:
INC dl ;小于,名次加1
A:
INC SI ;修改地址
INC SI
LOOP LOP2
POP CX
mov [BX+1], dl;把结果保存到高地址
INC BX ;修改地址
INC BX
add dl,30h ;输出
mov ah,02h
int 21h
LOOP LOP1 ;回到外面的循环
MOV AH,4CH
INT 21H
CODES ENDS
END START
2、汇编源程序,检查程序有否错误,有错时回到编辑状态,修改程序中错误行。无错时继续第3步。
3、连接目标程序,产生可执行程序。
4、DEBUG调试可执行程序,记录程序运行结果。
5、在操作系统状态下,运行程序,并记录程序运行结果。
453261
Press any key to continue
五、实验中各个步骤遇到的问题及解决方法、
1、汇编(masm/ML)
在设计方法上用到了俩重循环,在堆栈部分由于堆栈语句用的地方不对,导致有些计数器在进行下一次循环时没清零,所以在存放分数数组的俩个首址中,有个在进行下一次外循环时要清零,有个不需清零,把内外循环的层次理清后,出现的一些思想错误也能解决了。
2、连接(link)
3、调试(debug)
六、总结经验
循环设计程序最重要的是能写出循环的流程图,特别是对于多重循环,一定要理清各层循环之间的联系,如果信息存放在数组中,要搞清楚存放数组首址的寄存器是在哪层循环下要清零,还有就是为了方便地调用输出语句可以将想输出的内容存放在dl中。总之,写循环设计程序,我认为最重要的是清晰的思路和流程图。
第二篇:微处理器实验报告分支和循环程序设计
实验四
实验题目:
分支和循环程序设计
实验目的:
1、掌握分支程序编写方法
2、掌握循环程序设计的方法和技巧
3、学习程序调试的基本过程和方法
实验要求:
1、 阅读、运行并调试已给的分支和循环程序;
2、 模仿已给程序分别汇编程序和C51程序实现两个16位无符号数的比较的程序;
实验内容:
1. 分支程序设计:
(1)有两个8位无符号数NA、NB分别存放在内部RAM的40H,41H单元, 当NA<NB时,将内部RAM的42H单元置为0x88;当NA>=NB时将该单元置0xff。源程序如下:
汇编语言程序:
ORG 0000H
AJMP START
ORG 0100H
START:
MOV A ,40H //把(40H)中的值赋给累加器A
CJNE A, 41H, LOOP1 // 判断累加器A与41H中数。如果A=(41H),则顺序执行,如果A>=(41H),则Cy=0,否则Cy=1。如果A<(41H),则执行跳转语句LOOP1。
AJMP LOOP2 // 跳转到LOOP2
LOOP1:
JC LOOP3 //如果Cy=0,顺序执行,如果Cy=1,跳转到LOOP3
LOOP2:
MOV 42H, #0FFH //(42H)中赋值0xff
AJMP LOOP //跳转到LOOP
LOOP3 :
MOV 42H,#88H //(42H)中赋值0x88
LOOP:
AJMP LOOP
END
C51程序如下:
#include<reg51.h>
#include<absacc.h>
void main()
{unsigned char na,nb,f;
na=DBYTE[0x0040]; //把(0x0040)中的数赋给na
nb=DBYTE[0x0041]; //把(0x0041)中的数赋给nb
if(na<nb) f=0x88 ; //判断大小,
else f=0xff;
DBYTE[0x0042]=f; //给(0x0042)赋值f
}
(2)修改上汇编语言程序,实现两个16位无符号数的比较:当NA<NB时,将内部RAM的42H单元置为0x88;否则,当NA>=NB时将该单元置0xff。NA、NB分别存放在内部RAM的40H,41H及50H,51H单元。
提示:MCS-51指令系统没有16位比较指令,只能使用8位比较指令,于是应先比较两数的高8位,若NA的高8位小于NB的高8位,则说明NA<NB;将内部RAM的42H单元置为0x88。若NA高8位大于NB的高8位,则说明NA>NB;将42H单元置0xff。若NA的高8位等于NB的高8位,则再比较两者的低8位,方法同上(当NA=NB时,也将42H单元置0xff)。
2. 循环程序设计
(1)在片内RAM的10H单元存放一个8位无符号二进制数,要求将其每一位转换成相应的ASCII码,并以高位在前,低位在后的顺序依次存放到片内RAM以11H单元为首的连续单元中,编制相应的程序。
分析:用带进位的循环左移指令RLC,通过对C标志的判断,可知该位为1还是0。
ORG 0000H
AJMP START
ORG 0100H
START:
MOV R2,#08H R2中赋值08H,控制八位二进制数的转换
MOV R0,#10H R0中赋值(10H)这个地址,
MOV A,@R0 把地址(10H)中的数送到累加器A中
INC R0 R0中的地址变量加一
XUNHUAN:
RLC A 带标志位Cy左移一位
JC LOOP1 判断标志位,如果Cy=0,顺序执行,如果Cy=1,跳转到LOOP1
MOV @R0,#30H 对R0中的地址变量赋值
AJMP LOOP2
LOOP1:
MOV @R0,#31H 对R0中的地址变量赋值
LOOP2:
INC R0 R0中的地址变量加一
DJNZ R2, XUNHUAN 判断R2-1!=0时跳转到XUNHUAN
LOOP: SJMP LOOP
END
(2)编写该程序的C51程序。
提示:要判断一个字节中第i位(i=7-0)的值是0或1,可用第i位值为1的字节数与之按位相与,若结果为0,表明该位为0,反之为1。例如:数 0x82,即10000010,要判断第7位的值,可将0x82与0x80(即10000000,第7位为1)按位相与,结果不为0,所以0x82的第7位值为1。.
要在片内RAM 0x11地址连续存放转换后的ASCII码,可定义一个指向无符号单字节数的指针,将该指针的初值设为0x11,后在循环体内加1即可。
实验步骤:
1、分支程序的设计
阅读理解源程序的汇编语言代码和C语言代码。
在理解了8位数据的大小比较的基础上,编写汇编程序和C语言程序对16位的数据的大小进行比较。
2、循环程序的设计
(1) 对一个片内的地址中的8位二进制数,转换成ACSII码,并依次存放在一个连续的地址单元中。阅读理解这个汇编程序。
(2) 完成(1)的要求用C语言程序的编写代码。
实验代码:
16位数据的比较大小汇编语言代码:
ORG 0000H
AJMP START
ORG 0100H
START:
MOV A ,41H //把41H中的值赋给累加器A
CJNE A, 51H, LOOP1 //判断累加器A与51H中数。如果A=(51H),则顺序执行,如果A>=(51H),则Cy=0,否则Cy=1。如果A<(51H),则执行跳转语句LOOP1。
AJMP LOOP2 //跳转到LOOP2.对地位进行比较
LOOP1:
JC LOOP3 //如果Cy=0,顺序执行,如果Cy=1,跳转到LOOP3
MOV 42H,#0FFH //(42H)=0xff.
AJMP LOOP
LOOP2:
MOV A,40H // 把40H中的值赋给累加器A
CJNE A,50H,LOOP1 //断累加器A与50H中数。如果A=(50H),则顺序执行,如果A>=(50H), 则Cy=0,否则Cy=1。如果A<(50H),则执行跳转语句LOOP1。
LOOP3:
MOV 42H,#88H //(42H)=0x88.
LOOP:
AJMP LOOP
END
16位比较大小的C语言代码:
#include<reg51.h>
#include<absacc.h>
void main()
{unsigned char na,nb,nc,nd,f,g;
na=DBYTE[0x0040]; //把(0x0040)中的数赋给na
nb=DBYTE[0x0041]; //把(0x0041)中的数赋给nb
nc=DBYTE[0X0050];
nd=DBYTE[0X0051];
if(na<nc) f=0x88 ; //判断高八位的大小,如果na<nb,f=0x88
else f=0xff;
if(na==nc)
{if(nb<nd) f=0xff,g=0x88 ;
else f=0xff ,g=0xff;
}
DBYTE[0x0042]=f; //给(0x0042)赋值f
DBYTE[0x0052]=g; //给(0x0052)赋值g
}
8位二进制转换成ACSII码的C语言程序:
#include<reg51.h>
#include<absacc.h>
unsignedchar dsi[]={0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018};
//定义一个储存地址的数组
unsigned char code a[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
//定义一个数值数组
void main()
{
unsigned char na,nb;
unsigned int m;
int i;
na=DBYTE[0x10]; //把(0x10)中的数赋值给na
for(i=0;i<8;i++)
{
nb=a[i]; //取出数组a中的值赋值给nb
m=dsi[i]; //取出数组dsi中的地址赋给m
DBYTE[0x21]=na&nb; //na 和nb相与结果存在(0x21) 中
if(DBYTE[]==0x00) //判断如果(0x21)中的值等于0x00,地址m中的值赋为0x30,如果(0x21)中的值不等于0x00,地址m中就赋值为0x31
DBYTE[m]=0x30;
else
DBYTE[m]=0x31;
}
}
实验结果:
16位数据比较大小的汇编语言的结果:
16位数据比较大小的C语言的结果:
8位二进制转换成ACSII码的C语言程序:
输入的8位二进制数为0x3a
心得体会:
通过本学期的上机实验操作,我熟悉了Keil C,提高了自己的实际动手能力。这也为我今后继续使用学习这款软件打下了基础。同时在系统汇编语言方面得到了提高,虽然学院要求的知识阅读懂,但是我们在经过这次实验以后基本可以编写一些小程序了,以至于在以后的语言学习方面得到了很多启示和信心。
现实生活中,很多事情的成败取决于一些细节,即所谓“细节决定成败”,编写程序亦然,在这几次的实验中,我深感自己细节方面把握还不够,需要进一步加强。