📄 findhalf.asm
字号:
dseg segment
mess1 db 'no match !',13,10,'$'
mess2 db 'digiter ? ','$'
mess3 db 'offset adrres: ','$'
mess4 db 'segment addres: ','$'
startaddr dw 12,11,22,33,44,55,66,77,88,99,111,222,333;第一个数是个数
dseg ends
;******************************************
cseg segment
bsearch proc far
assume cs:cseg,ds:dseg,es:dseg
start:
push ds
sub ax,ax
push ax
mov ax,dseg
mov es,ax
mov ds,ax
mov di,offset startaddr ;首址->di
lea dx,mess2
mov ah,09h
int 21h
call decibin ;输入要查找的数
call crlf
mov ax,bx ;要查找的数->ax
add di,2 ;di是最前面的数的偏移
cmp ax,es:[di] ;是否<=最前面的数
ja chklast ;高于最前面的数,转,是否是最后一个数
lea si,es:[di] ;否则,最前面的数的地址到si
je alldone ;等于最前面的数,转显示结果
stc ;低于最前面的数,未找到,标志CX置于1
jmp exit
chklast:
mov di,offset startaddr ;是否>=最后一个数
mov si,es:[di]
shl si,1 ;个数乘2为长度
add di,si ;DI是最后一个数的偏移
cmp ax,es:[di] ;与最后一个数比较
jb search ;低于最后一个数,转查找(第一次默认在高值段)
je alldone ;等于最前面的数,转显示结果
stc ;高于最后一个数,未找到,标志CX置1
jmp exit
search: ;在高值段,求中间单元地址
mov di,offset startaddr ;数组首址->DI
mov si,es:[di] ;数组个数->SI
;注意!刚开始时,SI正好是半段长
mov startaddr,di ;保护数组首址
evenidx:
test si,1 ;检查半段长为奇数还是偶数
jz addidx ;是偶数转
inc si ;是奇数则长度加1
addidx:
add di,si ;!中间单元地址+下一段的半段长
;=高值段中间单元地址->DI
;!注意:第一次是数组首址+数组长度(半段长)+DI
compare:
cmp ax,es:[di] ;AX与中间单元比较
je alldone ;找到
ja higher ;!高于中间单元,下次在高值段查找
cmp si,2 ;若段长不为2字节,则表示未找到
jne idxok ;!若半段长不为字节,转低于中间单元,则在低值段查找
nomatch:
stc ;未找到标志CX置位
je alldone ;转显示结果
idxok:
shr si,1 ;求下次半段长
test si,1
jz subidx
inc si
subidx:
sub di,si ;!中间单元地址-下一段的半段长
jmp short compare ;=低值段的中间单元地址->DI
higher:
cmp si,2
je nomatch
shr si,1 ;求下次的半段长
jmp short evenidx
alldone:
mov si,offset startaddr
exit:
jc jm1
lea dx,mess3
mov ah,09h
int 21h
sub di,si
mov bx,di
call disp
call crlf
jmp jm2
jm1:
lea dx,mess1
mov ah,09h
int 21h
jm2:
ret
bsearch endp
;--------------------------------------------------------------
; 键入10进制数于BX中
decibin proc near
mov bx,0
newchar:
mov ah,1
int 21h
mov dl,al
sub al,30h
jl exit1
cmp al,9d
jg exit1
cbw
xchg ax,bx
mov cx,10d
mul cx
xchg ax,bx
add bx,ax
jmp newchar
exit1:
ret
decibin endp
;--------------------------------------------------------------
; 以16进制显示BX中的数
disp proc near
mov ch,4
rotate:
mov cl,4
rol bx,cl
mov al,bl
and al,0fh
add al,30h
cmp al,3ah
jl printit
add al,7h
printit:
mov dl,al
mov ah,2
int 21h
dec ch
jnz rotate
mov dl,'H'
mov ah,2
int 21h
ret
disp endp
;---------------------------------------------------------------
; 回车换行
crlf proc near
mov dl,0ah
mov ah,02h
int 21h
mov dl,0dh
mov ah,02h
int 21h
ret
crlf endp
;--------------------------------------------------------------
cseg ends
;--------------------------------------------------------------
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -