首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 汇编语言 >

汇编的程序出错了(帮小弟我看看吧)

2012-02-29 
汇编的程序出错了(帮我看看吧)程序语法没错,但是出来的结果不对,.modelsmall.stack40h.datanameparlabelby

汇编的程序出错了(帮我看看吧)
程序语法没错,但是出来的结果不对,
.model   small
.stack   40h
.data
namepar   label   byte
maxnlen   db   21
namelen   db   ?
namefld   db   21   dup(?)
telpar     label   byte
telmaxlen   db   9
tellen   db   ?
telfld   db   9   dup(?)
crlf     db   13,10, '$ '
endaddr   dw   ?
messg1   db   'Input   name:   ', '$ '
messg2   db   'Input   a   telephone   number: ', '$ '
messg3   db   'Do   you   want   a   telephone   number?(Y/N) ',13,10, '$ '
messg4   db   'name? ', '$ '
messg5   db     'name                                 telphone ',13,10, '$ '
namectr   db   0
tel_tab   db   50   dup(28   dup( '   '))
namesav   db   20   dup(?),13,10, '$ '
telsav   db   8   dup(?),13,10, '$ '
na_telsav   db   28   dup(?),13,10, '$ '
swapped   db   0
;******************************************************************************
.code
begin   proc   far
            mov   ax,@data
            mov   ds,ax
            mov   es,ax
            cld
            lea   di,tel_tab
      a:
            call   input_name
            call   inphone
            cmp     namelen,0
            jz       a30
            cmp     namectr,50
            je       a30
            call   stor_name
            call   stor_tel
            jmp     a
    a30:
            cmp   namectr,1
            jbe   a40
            call   name_sort
            call   println
            call   name_search
    a40:
            mov   ax,4c00h
            int   21h
           
;*****************************************************************************
input_name   proc   near
            mov   ah,09
            lea   dx,messg1
            int   21h
            mov   ah,0ah
            lea   dx,namepar
            int   21h
            mov   ah,09
            lea   dx,crlf
            int   21h


            mov   bh,0
            mov   bl,namelen
            mov   cx,21
            sub   cx,bx
      b:   mov   namefld[bx],20h
            inc   bx
            loop   b
            ret
input_name   endp
;******************************************************************************
stor_name   proc   near
          inc   namectr
          cld
          lea   si,namefld
          mov   cx,10
          rep   movsw
          ret
stor_name   endp
;********************************************************************************
inphone   proc   near
          mov   ah,09
          lea   dx,messg2
          int   21h
          mov   ah,0ah
          lea   dx,telpar
          int   21h
          mov   ah,09
          lea   dx,crlf
          int   21h
          mov   bh,0
          mov   bl,tellen
          mov   cx,9
          sub   cx,bx
    c:   mov   telfld[bx],20h
          inc   bx
          loop   c
          ret
inphone   endp
;***************************************************************************************
stor_tel   proc   near
          cld
          lea   si,telfld
          mov   cx,4
          rep   movsw
          ret

stor_tel   endp
;**************************************************************************************
name_sort   proc   near
          sub   di,48
          mov   endaddr,di
  g20:
          mov   swapped,0
          lea   si,tel_tab
  g30:
          mov   cx,28
          mov   di,si
          add   di,28
          mov   ax,di
          mov   bx,si
          repe   cmpsb
          jbe     g40
          call     chg
  g40:
          mov   si,ax
          cmp   si,endaddr
          jbe   g30
          cmp   swapped,0
          jnz   g20


          ret

name_sort   endp
;***************************************************************************************
chg   proc   near
          mov   cx,14
          lea   di,na_telsav
          mov   si,bx
          rep   movsw
          mov   cx,14
          mov   di,bx
          rep   movsw
          mov   cx,14
          lea   si,na_telsav
          rep   movsw
          mov   swapped,1
          ret
chg   endp
;************************************************************************************************
name_search   proc   near
        mov   ah,09
        lea   dx,messg3
        int   21h
        mov   ah,01
        int   21h
        cmp   al, 'N '
        jz     exit
        cmp   al, 'n '
        jz   exit
        mov   ah,09
        lea   dx,messg4
        int   21h
        call   input_name
        lea   di,tel_tab
comp:
        lea   si,namefld
        mov   cx,20
        repz   cmpsb
        jz       equal
        add     di,8
        jmp     comp
equal:
          mov   cx,8
          cld
          mov   si,di
          lea   di,telsav
          rep   movsb
          mov   ah,09
          lea   dx,telsav
          int   21h
         
exit:
          mov   ax,4c00h
          int   21h
name_search   endp
;***************************************************************************************
println   proc   near
          mov   ah,09
          lea   dx,messg5
          int   21h
          lea   si,tel_tab
  k20:
          lea   di,na_telsav
          mov   cx,14
          rep   movsw
          mov   ah,9
          lea   dx,na_telsav
          int   21h
          dec   namectr
          jnz   k20
          ret


println   endp
;************************************************************************************************
end   begin


[解决办法]
这是因为, 搜索 name 时, 虽然 name 总长度为 20, 但 repe cmpsb 不是等所有的 20 个字节都比较完了才终止的, 而是一旦遇到有不同的就终止了. 所以, repe cmpsb 后, di 不一定是指向了 name 的最后, 这样在匹配下一个记录时, 就不能简单的 add di, 8 了. 简单的还是先对 di 进行保存, 然后恢复, 增量以整个记录的长度:
comp:
push di ;*+ 保存 di
lea si,namefld
mov cx,20
repz cmpsb
pop di ;*+ 恢复 di 指向记录的开始
jz equal
add di,28 ;* 指向下一个记录的开始
jmp comp
equal:
mov cx,8
cld
lea si, [di+20] ;* 指向记录的 '号码 ' 域
...

热点排行