任务1:汇编程序及仿真
假设Device:STC15F2K60S2系列,工作时钟频率:12MHz。 汇编程序如下:
MyID EQU 201909070110 ;以学号为201909070110的学生为例
ORG 0000H
LJMP MAIN
ORG 0030H
MAIN: MOV A, #MyID ;A=2F 02B7 E9(1E)A累加器只有1字节
MOV B, #5
DIV AB ;A=A/B=1E/5=6,B=A%B=1E%5=0
MOV P0, B ;P0=0
MOV R0, #23H ;R0=23H
L1: MOV R1, #(MyID/5);R1=E91E/5=2E(9F)寄存器1字节,编译器运算2字节
L2: NOP
DJNZ R1, L2 ;R1=0
DJNZ R0, L1 ;R0=0,共运行23H*9FH次
MOV 30H, #0F0H ;(30H)=F0H
MOV R0, #30H ;R0=30H
RL A ;A*2=0CH
ANL A, @R0 ;A=00H
MOV P1, A ;P1=00H
L3: LJMP L3
END
试用以下两种方法: 1.通过查阅STC15系列指令集方法(不用计算机)(原期中考试题) 2.用Keil软件模拟方法(uVision4\project\options for…设置debug中选项use simulator) 回答以下问题: 问题1:什么是伪指令?本程序中哪些是伪指令? 伪指令(Pseudo Instruction)是用于对汇编过程进行控制的指令,该类指令并不是可执行指令,没有机器代码,只用于汇编过程中为汇编程序提供汇编信息 本程序中EQU,ORG,END是伪指令 问题2:下载到程序存储器时,相关单元地址、内容是什么? 地址 内容 指令 补充 C:0x0000 020030 LJMP MAIN(C:0030) C:0x0003 00 NOP C:0x0004 00 NOP C:0x0005 00 NOP C:0x0006 00 NOP C:0x0007 00 NOP C:0x0008 00 NOP C:0x0009 00 NOP C:0x000A 00 NOP C:0x000B 00 NOP C:0x000C 00 NOP C:0x000D 00 NOP C:0x000E 00 NOP C:0x000F 00 NOP C:0x0010 00 NOP C:0x0011 00 NOP C:0x0012 00 NOP C:0x0013 00 NOP C:0x0014 00 NOP C:0x0015 00 NOP C:0x0016 00 NOP C:0x0017 00 NOP C:0x0018 00 NOP C:0x0019 00 NOP C:0x001A 00 NOP C:0x001B 00 NOP C:0x001C 00 NOP C:0x001D 00 NOP C:0x001E 00 NOP C:0x001F 00 NOP C:0x0020 00 NOP C:0x0021 00 NOP C:0x0022 00 NOP C:0x0023 00 NOP C:0x0024 00 NOP C:0x0025 00 NOP C:0x0026 00 NOP C:0x0027 00 NOP C:0x0028 00 NOP C:0x0029 00 NOP C:0x002A 00 NOP C:0x002B 00 NOP C:0x002C 00 NOP C:0x002D 00 NOP C:0x002E 00 NOP C:0x002F 00 NOP C:0x0030 741E MOV A,#0x1E C:0x0032 75F005 MOV B(0xF0),#0x05 C:0x0035 84 DIV AB C:0x0036 85F080 MOV P0(0x80),B(0xF0) C:0x0039 7823 MOV R0,#0x23 C:0x003B 799F MOV R1,#0x9F C:0x003D 00 NOP C:0x003E D9FD DJNZ R1,L2(C:003D) C:0x0040 D8F9 DJNZ R0,L1(C:003B) C:0x0042 7530F0 MOV 0x30,#B(0xF0) C:0x0045 7830 MOV R0,#0x30 C:0x0047 23 RL A C:0x0048 56 ANL A,@R0 C:0x0049 F590 MOV P1(0x90),A C:0x004B 02004B LJMP L3(C:004B) 问题3:每行程序单句执行时间(单位uS)?(一个机器周期大约是1uS)
MyID EQU 201909070110 ;以学号为201909070110的学生为例
ORG 0000H
LJMP MAIN ;2个周期
ORG 0030H
MAIN: MOV A, #MyID ;1个周期
MOV B, #5 ;2个周期
DIV AB ;4个周期
MOV P0, B ;2个周期
MOV R0, #23H ;1个周期
L1: MOV R1, #(MyID/5);1个周期
L2: NOP ;1个周期
DJNZ R1, L2 ;2个周期
DJNZ R0, L1 ;2个周期
MOV 30H, #0F0H ;2个周期
MOV R0, #30H ;1个周期
RL A ;1个周期
ANL A, @R0 ;1个周期
MOV P1, A ;1个周期
L3: LJMP L3 ;2个周期
END
问题4:标号L1行处,运算(MyID/5)是谁做的? 编译器:直接计算的只截取了MyID的低两个字节
问题5:该段程序(执行到L3时)总执行时间(单位uS)? 所用时钟周期数目为2+1+2+4+2+1+(1+(2+1)159+2)35+2+14+2=16820个时钟周期 所以总用时为1216820/(12*106)*106=16820uS 问题6:程序执行结束时,P0、P1的值为多少? P0=00H,P1=00H 参考资料:STC15系列数据手册_2021版.pdf
任务2:C程序及仿真
Keil C源程序如下: char chara,charb,charc; int inta,intb,intc; void main() { chara=400;//越界了,实际值可能为-112 inta=300; charb=chara+inta;//188,越界,实际为-68 if( charb > 0 ) charc=200;//不满足 else charc=300;//满足,越界,实际为44 intb=chara+inta;//188 if( intb > 0 ) intc=200;//满足 else intc=300; while(1); } 回答以下问题: 问题1:通过阅读源程序,回答程序执行到while(1)时: charb=-68 intb=188 charc=44 intc=200 问题2:用Keil软件模拟方法,通过软件模拟回答: charb=90H(-68) intb=00BCH(118) charc=2CH(44) intc=00C8(200)
问题3:这段C语言源程序,Keil编译器编译链接后生成的汇编和机器码程序是什么?机器码程序在程序存储器中的存储地址是? 生成的汇编程序和机器码程序为: 指令地址 机器码 汇编程序 C:0x0000 02004F LJMP C:004F C:0x0003 750890 MOV chara(0x08),#P1(0x90) C:0x0006 750B01 MOV inta(0x0B),#0x01 C:0x0009 750C2C MOV 0x0C,#0x2C C:0x000C E508 MOV A,chara(0x08) C:0x000E 250C ADD A,0x0C C:0x0010 F509 MOV charb(0x09),A C:0x0012 D3 SETB C C:0x0013 6480 XRL A,#P0(0x80) C:0x0015 9480 SUBB A,#P0(0x80) C:0x0017 4005 JC C:001E C:0x0019 750AC8 MOV charc(0x0A),#0xC8 C:0x001C 8003 SJMP C:0021 C:0x001E 750A2C MOV charc(0x0A),#0x2C C:0x0021 AF08 MOV R7,chara(0x08) C:0x0023 EF MOV A,R7 C:0x0024 33 RLC A C:0x0025 95E0 SUBB A,ACC(0xE0) C:0x0027 FE MOV R6,A C:0x0028 E50C MOV A,0x0C C:0x002A 2F ADD A,R7 C:0x002B F50E MOV 0x0E,A C:0x002D E50B MOV A,inta(0x0B) C:0x002F 3E ADDC A,R6 C:0x0030 F50D MOV intb(0x0D),A C:0x0032 D3 SETB C C:0x0033 E50E MOV A,0x0E C:0x0035 9400 SUBB A,#0x00 C:0x0037 E50D MOV A,intb(0x0D) C:0x0039 6480 XRL A,#P0(0x80) C:0x003B 9480 SUBB A,#P0(0x80) C:0x003D 4008 JC C:0047 C:0x003F 750F00 MOV intc(0x0F),#0x00 C:0x0042 7510C8 MOV 0x10,#0xC8 C:0x0045 8006 SJMP C:004D C:0x0047 750F01 MOV intc(0x0F),#0x01 C:0x004A 75102C MOV 0x10,#0x2C C:0x004D 80FE SJMP C:004D C:0x004F 787F MOV R0,#0x7F C:0x0051 E4 CLR A C:0x0052 F6 MOV @R0,A C:0x0053 D8FD DJNZ R0,C:0052 C:0x0055 758110 MOV SP(0x81),#0x10 C:0x0058 020003 LJMP main(C:0003) C:0x0000~0x0058 问题4:6个变量(chara,charb,charc,inta,intb,intc)具体分配的存储单元地址?char,int分别占用存储单元的字节数? Chara:0x08 Charb:0x09 Charc:0x0A Inta:0x0B Intb:0x0D Intc:0X0F Char ,int 分别占用1个和2个字节 问题5:什么是大端存储和小端存储?仿真时通过查看具体变量inta,intb,intc存储单元存放的数据情况,回答它们的存储方式是大端还是小端? 大端存储:高位数据存储在高地址 小端存储:低位数据存储在低地址
提示:仿真时,可打开view下的以下窗口,同时单步执行程序观查 ?Disassembly Window ?Symbol Window ?Memory Window 任务3:C语言程序设计(算法与算法评价) 一、编程训练(注意正确使用数据类型) 在STC-BSP环境下用所提供的API函数,给“STC-B学习板”编写程序,实现如下功能: 设时钟的时分秒分别为:HH (BCD码,范围:0~23) MM (BCD码,范围:0~59) SS (BCD码,范围:0~59) 若把“SSMMHH”看成是一个16进制数0xSSMMHH(如上午9时30分10秒,则看成0x103009),请编写程序把SS-MM-HH和0xSSMMHH的10进制值在数码管上交替显示出来。设SSMMHH随时间变化(一秒变一次,也可在实时时钟DS1302中获取实时时钟值)。
#include "STC15F2K60S2.H"
#include "sys.H"
#include "displayer.H"
#include "beep.h"
code unsigned long SysClock=11059200;
#ifdef _displayer_H_
#ifdef _displayer_H_
code char decode_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x08,0x40,0x01, 0x41, 0x48,
0x3f|0x80,0x06|0x80,0x5b|0x80,0x4f|0x80,0x66|0x80,0x6d|0x80,0x7d|0x80,0x07|0x80,0x7f|0x80,0x6f|0x80,
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,~0xbf,~0xdf,~0xef,~0xf7,~0xfb,~0xfd,~0xfe};
char count=5;
char flag=1;
unsigned long int time_num;
long int second=0;
long int minute=0;
long int hour=0;
void Call_Back_100S()
{
if(count!=5)
count++;
else
{
if(flag==1)
{
if(second!=59)
second++;
else
{
second=0;
if(minute!=59)
minute++;
else
{
minute=0;
if(hour!=23)
hour++;
else
hour=0;
}
}
Seg7Print(second/10,second%10,12,minute/10,minute%10,12,hour/10,hour%10);
}
else
{
time_num=second*16*16*16*16+minute*16*16+hour;
Seg7Print(0,time_num/1000000%10,time_num/100000%10,time_num/10000%10,time_num/1000%10,time_num/100%10,time_num/10%10,time_num%10);
}
flag=-flag;
count=0;
}
}
void main()
{
BeepInit();
DisplayerInit();
SetDisplayerArea(0,7);
MySTC_Init();
SetEventCallBack(enumEventSys100mS,Call_Back_100S);
while (1)
{
MySTC_OS();
}
}
二、(选做)程序及算法优化 利用STC-BSP中sys模块提供的GetSysPerformance() 函数(每秒获取一次即可)获取程序性能评估参数: SysPerformance.MainLoops:每秒主循环数(应>1000,越大越好) SysPerformance.PollingMisses:每秒轮询丢失数(应为0) 改进程序和算法,在程序效果不变前提下,提供程序性能,即: PollingMisses=0 MainLoops数值尽量大
|