折半查找:在首地址为ARRAY开始的内存单元中存有10个字节数,判断是
否存在某个数,并输出结果(存在输出‘YES’,不存在输出‘NO’)。
数据段如下:
DATAS SEGMENT
ARRAY DB 11,22,33,44,55,66,77,88,99,110
X DB 88
YYY DB 'YES',13,10,'$'
NNN DB 'NO',13,10,'$'
DATAS ENDS
DATAS SEGMENT
ARRAY DB 11,22,33,44,55,66,77,88,99,110
YES DB ' YES!',13,10,'$'
NO DB ' NO!',13,10,'$'
X DB 88
DATAS ENDS
STACKS SEGMENT
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
; 以下注释掉的为可输入折半查找法
; MOV AH,1 ;输入第一位
; INT 21H
; MOV AH,10
; SUB AL,'0' ;存放的是ASCII码,减0变成十进制
; MUL AH ;第1位乘10才是十位
; MOV DH,AL ;先把十位放到dh
; MOV AH,1 ;输入第二位
; INT 21H
; SUB AL,'0'
; ADD DH,AL ;十位和个位相加,放到dh中
; MOV AL,DH
MOV AL,X
MOV BX,0 ;BX放最小数的下标
MOV SI,10 ;SI放的是最大数的下标
DEC SI
L1:CMP BX,SI ;如果BX比SI大,说明最小数的下标移动到最大的后面去了
JA L4 ;没有找到
MOV DI,BX
ADD DI,SI ;DI+SI
SAR DI,1 ;将DI右移一位 相当于求中间点
CMP AL,ARRAY[DI] ;比较AL与当前的中间点
JE L3 ;如果相等表明找到了该字符 跳转到L3段
JA L2 ;如果大于则跳到L2段
DEC DI
MOV SI,DI ;小于的话 将右边界点向前移动到中间点的前面那一点
JMP L1 ;跳转到L1段(下一轮循环)
L2:INC DI
MOV BX,DI ;将左边界点向后移动移动到中间点的后面那一点
JMP L1 ;跳转到L1段(下一轮循环)
L3:LEA DX,YES
JMP L5 ;跳转到L5段(输出语句)
L4:LEA DX,NO
L5:MOV AH,9
INT 21H
MOV AH,4CH
INT 21H
CODES ENDS
END START
运行结果: