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;
}