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

汇编关于ret如何没有返回到正确的地方?

2012-02-09 
汇编关于ret怎么没有返回到正确的地方??这个程序整体是关于输入人名,输入电话号码,存进tel_tab中,制成一个

汇编关于ret怎么没有返回到正确的地方??
  这个程序整体是关于输入人名,输入电话号码,存进tel_tab中,制成一个电话本。再做查找,输出想要查找的人名的号码。
整个程序debug了貌似没什么问题,只是主要有个问题就是在search那个子程序里,那个子程序最后的ret返回的位置不对,用debug时发现的,不知道它为什么会乱跳,是因为堆栈的问题吗,不大明白哪出问题了,后来我就把那个search子程序删掉,并把里面的内容整个复制,贴到主程序里了,这样没了ret就运行正常了。        
但是!!我还是想知道为什么???!!哪里的问题!!!!
高手帮忙解答一下呗!!

data     segment
;   namepar         label         byte
  maxnlen         db               21
  namelen         db               ?
  namefld         db               21   dup(?)

  numberpar     label         byte
  maxmlen         db               9
  numlen           db               ?
  numfld           db               9   dup(?)

  judge             label         byte
  maxjlen         db               2
  judgelen       db               ?
  judgefld       db               2   dup(?)

  crlf               db               13,10, '$ '
  tel_tab         db               50   dup(28   dup(?))
  table             db               28   dup(?),13,10, '$ '

  messg1           db               'name                                 tel. ',13,10, '$ '
  messg2           db               'Input   name: ', '$ '
  messg3           db               'Input   a   telephone   number: ', '$ '
  messg4           db               'Do   you   want   a   telephone   number? ',13,10, '$ '
  messg5           db               'name? ',13,10, '$ '
  messg6           db               'No   match! ', '$ '

  endaddr         dw               ?
  have_xchd     db               0
  printit         db               0

  data   ends
;--------------------------------------


  code     segment
  main     proc     far
              assume   cs:code,ds:data

  mov     ax,data


  mov     ds,ax
  mov     es,ax

  mov     cx,50
  lea     di,tel_tab

  loop1:
            cmp       cx,0
            jz         sort
            call     input_name
            cmp       namelen,0
            jz         sort              
            call     stor_name

            mov       ah,09h
            lea       dx,messg3
            int       21h

            call     inphone
            dec       cx
            jmp       loop1

  sort:
            cmp       cx,50
            jz         over
            call     name_sort

  y_or_n:
            mov       ah,09h
            lea       dx,messg4
            int       21h
                                                 
            mov       ah,0ah
            lea       dx,judge
            int       21h

            mov       al,judgefld
            cmp       al,4eh
            jz         over
            cmp       al,59h
            jne       y_or_n
            mov       ah,09h
            lea       dx,messg5
            int       21h
            call     input_name
            call     name_search
            jmp       y_or_n                                                                               ;ret该返回的位置

  over:
            mov       ax,4c00h
            int       21h

  main   endp
;--------------------------------------------
  input_name     proc   near

  push       cx


  mov         ah,09h
  lea         dx,messg2
  int         21h
  mov         ah,0ah
;   lea         dx,namepar
  lea         dx,maxnlen
  int         21h
  mov         ah,09h
  lea         dx,crlf
  int         21h

  mov         bh,0
  mov         bl,namelen
  mov         cx,21
  sub         cx,bx
 

  to_blank:
                  mov       namefld[bx],20h
                  inc       bx
                  loop     to_blank
                  pop       cx
                  ret

  input_name       endp

;------------------------------------------------
  stor_name     proc     near

  push       cx
  cld
  lea         si,namefld
;   lea         di,tel_tab
  mov         cx,20
  rep         movsb
  pop         cx
  ret

  stor_name     endp

;-------------------------------------------------
  inphone     proc     near

  push       cx                                                  
  mov         ah,0ah
  lea         dx,numberpar
  int         21h

  mov         ah,09h
  lea         dx,crlf
  int         21h
  cld
  lea         si,numfld
  mov         cx,8
  rep         movsb
  pop         cx
  ret

  inphone   endp

;-------------------------------------------------
  name_sort     proc     near

  push     di
  lea       di,tel_tab

  mov       ax,50
  sub       ax,cx
  dec       ax
  mov       bx,28
  imul     bx
  add       di,ax                                                            
  mov       endaddr,di
 
  sort0:
            mov       have_xchd,0
            lea       si,tel_tab

  sort1:


            mov       di,si
            mov       cx,20
            cld
            add       di,28
            mov       ax,di
            mov       bx,si
        ;     cmp       di,endaddr
        ;   jz         sort0
            repe     cmpsb
            jbe       no_xche
            call     yes_xche

  no_xche:

          mov       si,ax                                      
          cmp       si,endaddr
          jb         sort1
        ;   jbe       sort1
          cmp       have_xchd,0
          jnz       sort0
     
          pop       di
          ret

  name_sort   endp
;---------------------------------------------
  yes_xche     proc     near

  push     di
  mov       cx,28
  lea       di,table
  mov       si,bx
  rep       movsb

  mov       cx,28
  mov       di,bx
  rep       movsb

  mov       cx,28
  lea       si,table
  rep       movsb
  mov       have_xchd,1
  pop       di
  ret

  yes_xche   endp
  ;--------------------------------------------
  name_search   proc     near                                                               ;问题所在子程序,这是一个查询搜索

  push       di
  lea       di,tel_tab
  mov       ax,endaddr
  add       ax,28
  compare:
                lea       si,namefld                                
                mov       printit,0
                mov       bx,di
                mov       cx,20
            ;     push     si
                cld
                repe     cmpsb


              ;   pop       si
                jne       go_on
                call     printline

  go_on:
                mov         di,bx
                add         di,28
                cmp         printit,1
                jz           exit
                cmp         di,ax
                jb           compare

                mov         ah,09h
                lea         dx,messg6
                int         21h
                pop         di

  exit:   ret                                             ;这个ret返回的位置不固定貌似,它怎么乱跳呢它,按道理讲它应该返回到上面注释的     那个位置吧?就是这里不会。
  name_search     endp
  ;-------------------------------------------

  printline     proc     near

  push       di
  push       cx
  mov         ah,   09h
  lea         dx,messg1
  int         21h

  mov         cx,28
  cld
  lea         di,table
  mov         si,bx
  rep         movsb

  mov         ah,09h
  lea         dx,table
  int         21h

  mov       printit,1
  pop       cx
  pop       di

  ret

  printline     endp

;-----------------------------------------------
  code   ends
  end     main



[解决办法]
ret 不能正确返回,无法是子程里的堆栈操作不平衡,或者是无意破坏了堆栈里的内容。你这里,那个子程中的 exit: 标号位置错了,应该在 pop di 指令之前;现在的样子导致子程开始时压栈的 di 没有被出栈,致使堆栈没平衡,ret 指令就返回到了错误的地方。

热点排行