org 0000
ljmp start
org 1000
TAB: DB 0EEH,0DEH,0BEH,7EH,0EDH,0DDH
start:
mov DPTR,#start
;将dptr low,dptr high压栈,保存start地址,以便ret指令返回
push dpl
push dph
mov A,#0EEH
mov 20H,A
;置键码表TAB表首地址
;A为表起始地址偏移量
mov DPTR,#TAB
mov A,#0
next:
;保存A寄存器中的值
push acc
movc A,@A+DPTR ;A为TAB编码
;讲20H的值与A比较,如果不相等跳转
CJNE A,20H,notequal
;如果相等
pop acc
RL A ;得分支表内部偏移(x2,8位变16位)
mov DPTR,#APJ ;置分支表首地址
JMP @A+DPTR ;执行表跳转
notequal:
pop acc
inc A
;如果A的值为6退出循环
CJNE A,#6,next
SJMP $
APJ:
AJMP PR0
AJMP PR1
AJMP PR2
AJMP PR3
AJMP PR4
;RET 返回指令,就会用刚刚压入两字节数据,当做返回地址。
PR0:
RET
PR1:
RET
PR2:
RET
PR3:
RET
PR4:
RET
end
#include<reg51.h>
void PR2();
void PR0();
void PR1();
void main() {
PR2();
}
//P75-7
void PR0() {
char i;
//声明存储单元指针
char *Ppos = 0x40;
char *Pneg = 0x50;
char *Pdata = 0x30;
//声明计数变量
char R4 = 0; //pos
char R5 = 0; //neg
char R6 = 0; //zero
//定义数据
char datas[16] = {2,4,6,8,10,0,-1,-3,-5,-7,-9};
//数据存入0x30
//正数存入0x40,负数存入0x50
for(i=0; i<16; i++) {
*(Pdata++) = datas[i];
if(datas[i]>0) {
*(Ppos++) = datas[i];
R4++;
}
if(datas[i]<0) {
*(Pneg++) = datas[i];
R5++;
}
if(datas[i]==0) {
R6++;
}
}
}
//P75-9
void PR1() {
#define DATA 0X10
char ADC=0;
char i=0;
char data *d = DATA;
//定义4字节数
*d = 0xAA;
*(d+1) = 0xAA;
*(d+2) = 0xAA;
*(d+3) = 0xAA;
//进位标志
//逐字节取反
for(i=0; i<4; i++) {
*(d+i) = ~*(d+i);
}
//加一
if(*d==0xFF) {
*d=0;
ADC=1;
} else {
//加一
(*d)++;
//d->d+1
d++;
}
for(i=1; i<4; i++) {
//如果此字节为FF且有进位
if(*d==0xFF&&ADC==1) {
ADC=1;
*d=0;
}
//此字节不为FF但有进位
else if(ADC==1) {
(*d)++;
ADC=0;
}
d++;
}
}
void PR2() {
#define BUF1 0x60
#define BUF2 0x10
#define BUF 0x00
//定义数据
unsigned char sets[16] = {0x05,0x0F,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};
unsigned char sum=0;
unsigned char avg=0;
unsigned char rem=0;
char i;
unsigned char xdata *dx = BUF1;
unsigned char data *davg = BUF2;
unsigned char data *drem = BUF;
//存储外部数据
for(i=0; i<16; i++) {
*dx = sets[i];
dx++;
}
//恢复dx起始地址
dx = BUF1;
//求累加值
for(i=0; i<16; i++) {
sum += *dx;
dx++;
}
avg = sum/16;
rem = sum%16;
*davg = avg;
*drem = rem;
}