📄 find.asm
字号:
;查找数据包起始位置的算法。
MONTH DATA 33H ;月份存放单元。
DAY DATA 34H ;日期存放单元。
N DATA 35H ;批次存放单元。
ORG 0000H
LJMP TEST
ORG 100H
TEST: MOV P2,#20H ;将模拟调试数据装入片外RAM中。
MOV R0,#80H
MOV DPTR,#DATS
MOV R2,#16
LOOP: CLR A
MOVC A,@A+DPTR
MOVX @R0,A
INC R0
INC DPTR
DJNZ R2,LOOP
MOV MONTH,#8;查找8月15日第3批次的数据起始地址。
MOV DAY,#15H
MOV N,#3
LCALL FNST ;查找成功,起始地址为208CH。
MOV MONTH,#8;查找8月16日第1批次的数据起始地址。
MOV DAY,#16H
MOV N,#1
LCALL FNST ;查找失败。
STOP: LJMP STOP
DATS: DB 00H,0FFH,0FFH,08H
DB 15H,03H,0FFH
DB 0FFH,0FFH,08H
DB 15H,03H,0F0H
DB 05H,05H,0FFH
FNST: MOV DPTR,#2040H;从数据区首址开始。
MOV R2,#20H ;最多访问1FC8H个字节。
MOV R3,#0C8H
MOV R4,#0 ;初始化内容为0FFH的连续单元长度计数器。
FN1: MOVX A,@DPTR ;读取一个字节。
CJNE A,#0FFH,FN2;内容是0FFH吗?
INC R4 ;是,计数器加一。
MOV A,R4 ;判断计数器当前值。
JNZ FN3 ;继续查找。
MOV R4,#3 ;如果加一以后是0,实际上是256,保留3个。
LJMP FN3 ;继续查找。
FN2: CLR A ;不是0FFH。
XCH A,R4 ;取出计数器的当前值,再清除计数器。
ADD A,#0FDH ;已经有3个或3个以上连续单元内容均为0FFH?
JNC FN3 ;没有,继续查找。
MOVX A,@DPTR ;前面已经有3个或3个以上0FFH,读取当前内容。
CJNE A,MONTH,FN3;是指定月份吗?
LCALL IDP ;是,调整指针到下一个单元。
MOVX A,@DPTR ;读取内容。
CJNE A,DAY,FN3;是指定日期吗?
LCALL IDP ;是,调整指针到下一个单元。
MOVX A,@DPTR ;读取内容。
CJNE A,N,FN3 ;是指定批次吗?
LCALL IDP ;是,调整指针到下一个单元,即数据开始地址。
SETB F0 ;查找成功。
RET ;返回。
FN3: LCALL IDP ;调整指针到下一个单元。
DJNZ R3,FN1 ;查找完全部范围吗?
DJNZ R2,FN1
CLR F0 ;找不到,失败。
RET ;返回。
IDP: INC DPTR ;指针加一。
MOV A,DPH ;判断地址高字节。
JNB ACC.6,IDPE;是40H吗?
MOV DPTR,#2040H;返回2040H。
IDPE: RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -