一、实验题目:
(汇编)若0-5号键的键值分别是:EEH、DEH、BEH、7EH、EDH、DDH。设键值存放在内部RAM 20H单元中,编程实现根据2OH中的键值分别使程序转移到PR0-PR4程序段。要求当以上程序段的功能完成后,都采用RET指令,指定返回到程序的初始入口START标号处。
(C语言)新建工程用C语言完成1题
要求:PR0 :教材75页习题7
PR1 :同上 习题9题
PR2:同上 习题10
其余入口,只需完成空操作就返回。
PR3-4:ABCchar定义三个变量
二、实验目的
1、掌握散转的编程方法。
2、掌握指定返回的编程方法。
三、实验要求:
1、独立完成实验内容。
2、掌握在Keil中调试程序的方法。
3、掌握在Keil中建立存储器窗口的方法(C、D、X)
4、 提供实验报告(电子档)
四、实验主要流程、基本操作或核心代码、算法片段(该部分如不够填写,请另加附页)
汇编代码:
BUF2 EQU 0A0H
BUF EQU 11H
BUF1 EQU 0CCH
DATA1 EQU 04H
ORG 0000H
LJMP STRAT
ORG 0100H
STRAT:
MOV DPTR ,#STRAT
push dph
push dpl
MOV DPTR,#TAB ;键值表的 起始位置
MOV R0,#0FFH ;循环计数,初始为-1
NEXT:
INC R0 ;自加
MOV A,R0
MOVC A,@A+DPTR
CJNE A,B,NEXT ;A与B的内容比较 现在查的键值存在B中,不等,循环键值表下一个单元
MOV A,R0 ;键值表第几个位置送给A
MOV DPTR,#JPT
RL A ;计算偏移 :A=A*2,AJMP为两字节指令,R0对应PR0,R1对应PR1。。。。。
;若R0=2,变址A*2后为4,跳过4个字节到PR2处
JMP @A+DPTR ;间接跳转到对应函数 基址JPT加变址RL A JMP间接转移
PR0:
MOV R7,#10H ;16个数据 十进制数10=16进制数10H
MOV A,#0
MOV R4,A
MOV R5,A
MOV R6,A
MOV R0,#40H
MOV R1,#50H
mov R3,sp
MOV SP,#3FH ;指针指向3FH地址,从内部存储器30H单元开始,SP指向末地址
NEXT1:
POP ACC ;弹出从内部存储器30H单元开始的元素的末地址的元素
JZ ZER0 ;判断是否为0
JB ACC.7 ,NE1 ;最高位为1,为负数
INC R4 ;正数个数加一
MOV @R0,A ;存入R0地址,即40H地址
INC R0 ;地址加一
AJMP DJ
NE1:
INC R5 ;负数个数加一
MOV @R1,A ;存入R1地址,即50H地址
INC R1 ;地址加一
AJMP DJ
ZER0:
INC R6
DJ:
DJNZ R7,NEXT1 ;R7减1与0比较,不相等跳转
mov sp,R3
RET
;/*将存放在DATA1单元开始的一个4字节数去补后送回原单元*/
PR1:
MOV R7,#03H ;4字节数,用于高字节循环判断
MOV R0,#DATA1
IN:
INC R0
DJNZ R7,IN
MOV A,@R0
JB ACC.7,FUSHU ;和1比较,判断负数
RET
FUSHU:
MOV R7,#03H
MOV R0,#DATA1
MOV A,@R0 ;将DATA中的值送入A
CPL A ;低字节求补 ;取反
ADD A,#01 ;加一
MOV @R0,A ;送回原地址
AB1:
INC R0 ;下一个字节
MOV A,@R0
CPL A ;取反
ADDC A,#0 ;加上低字节的进位
DJNZ R7,AB1 ;减1和0比较,高字节循环3次
RET
;以BUF1为起始地址的外存储器中,存放着16个单字节无符号二进制数,
;将平均值存入BUF2,余数存入BUF
PR2:
MOV R7,#0FH ;16个数据
MOV R0,#BUF1
MOV B,#0 ;存和的高位
MOV A,@R0 ;取BUF1为起始地址的外存储器的首地址的值
MOV R2,A ;暂存R2
NEXT2:
MOV A,R2
INC R0 ;BUF1下一个地址
ADD A,@R0 ;数据求和,地位存于A
MOV R2,A ;暂存R2
MOV A,B
ADDC A,#0
MOV B,A ;存数据高位,加上进位
DJNZ R7,NEXT2 ;数据读完
MOV R6,#04H ;右移4次实现除以16
MOV BUF2,A ;低位数据暂存于BUF2
MOV BUF,#0 ;存余数
NEX:
CLR C ;清空C
MOV A,B ;B中高位数据送给A进行右移
RRC A
MOV B,A ;右移后的高位数据暂存于B
MOV A,BUF2 ;暂存于BUF2的低位数据送给A
RRC A ;低位数据进行右移
MOV BUF2,A ;右移后的低位数据暂存于BUF2
MOV A,BUF
RRC A
MOV BUF,A
DJNZ R6,NEX ;求商,余数(右循环四次实现除以16)
MOV A,BUF
SWAP A
RET
PR3:
NOP
RET
PR4:
NOP
RET
JPT:
AJMP PR0
AJMP PR1
AJMP PR2
AJMP PR3
AJMP PR4
TAB:DB
0EEH,0DEH,0BEH,07EH,0EDH,0DDH ;键值表
END
/*从内部存储器30H单元开始,有16个数据,将其中的正数,负数分别存入40H和50H开始的存储单元,并分别将正数,负数,零的个数存入R4,R5,R6中
*/
C语言代码:
#include
#include
#include
#define uint unsigned int
#define uchar unsigned char
#define BUF1 0x80
#define BUF2 0x90
#define BUF 0x72
#define DATA 0x65
uchar key_value[6]={0xEE,0xDE,0xBE,0x7E,0xED,0xDD}; //0-5号的键值
/*
PR0:从30H开始,有16个数据,正数和负数分别存放在40H和50H中,将正数负数和零的个数存入R4,R5,R6
/*
(*p)++,是先取指针P的值,然后对其值进行++运算,*(p++),是先对指针P进行++运算,然后再取取值。
*的作用是使用P指针指向数据。
例如:假设int*P=1,那么*P++值为2.假设int
array[5]; int *p = a; p++之后 p=&array[1];
也就是所,p指针自加也就是说p指向p之后的数据单元,本来p指向array[0]的,自加就指向array[1].
*/
*/
void PR0(){
uint i,R4,R5,R6 ;
uchar table[]={1,2,3,-4,4,5,6,-6,-7,-8,0,-9,-10,-11,0,0}; //16个数据
uchar *p=0x30; //开始30H指针
uchar *px=0x40; //存正数
uchar *py=0x50; //存负数
for(i=0;i<16;i++){
if(table[i]>0){
R4++; //正数个数
(*px++)=table[i]; //
}
else if(table[i]<0){
R5++; //负数个数
(*py++)=table[i];
}
else
R6++; //0的个数
}
}
void PR1(){
char data *p = DATA;
char data *q = p+3;
uchar i,cy=0;
*(q)=0x0f4;
if((*(q)&0x80)!=0)
{
for(i=0;i<4;i++,p++)
{
*p=~*p;
}
p=DATA;
if(0x0ff==*p) //DATA 11111111 --00000000
{
cy++;
*p=0;
}
else (*p)++;
for(i=1,p++;i<3;i++,p++)
{
if(*p==0x0ff&&cy==1)
{
cy=1;
*p=0;
}
else if(cy==1)
{
(*p)++;
cy=0;