⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 findhalf.asm

📁 用汇编对个数确定的数组进行折半查找,并显示最后结果
💻 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 + -