. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->CALL和RET指令
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  第十章实验第三个子程序搞不掂,帮帮我。  [待解决] 回复[ 10次 ]   点击[ 524次 ]  
cairulong
[帖 主]   [ 发表时间:2008-06-07 18:26 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-04-27 16:45
assume cs:code,ds:data,ss:stack
data segment
db 10 dup(0)
data ends        
stack segment
db 16 dup(0)
stack ends
code segment
start:  mov ax,data
        mov ds,ax
        mov ax,12666
        mov si,0
        call dtoc
        mov ax,4c00h
        int 21h
;-------------------------------------------------------------------
;名称:dtoc 
;功能:将WORD型数据变为表示十进制数的字符串,字符串以0为结尾符。
;参数:(ax)=word型数据,ds:si指向字符串的首地址
;返回:无
dtoc:   
        mov cx,0
        push cx
      s0:mov cx,0Ah
        call divdw
        add cl,30h
        push cx ;将余数压入栈,做交换准备
        mov cx,ax 
        jcxz exit0 ;判断商是否为零
         jmp short s0        
  exit0:pop cx
        jcxz s2 
        mov ds:[si],cl
        inc si
        jmp short exit0        
     s2:mov dh,1
        mov dl,1
        mov cl,12
        mov si,0
        call show_str
        ret
;-----------------------------------------------------------------------
;名称:divdw  
;公式:x/n=int(H/n)*65535+[rem(H/n)+L]/n 
;功能:进行不会产生溢出的除法,被除数为DWORD型,除数为WORD型,结果为DWORD 
;参数:(ax)=dword型的数据的低16位(DX)=DWORD型数据的高16位,(CX)除数 
;返回:(DX)=结果的高16位,(AX)=结果的低16位,(CX)=余数         
divdw:
        push ax
        mov ax,dx
        mov dx,0
        div cx
        mov bx,ax
        pop ax
        div cx
        mov cx,dx
        mov dx,bx                
        ret
;-------------------------------------------------------------------------------
;显示字符串子程序 
;名称:show_str 
;功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串 
;参数:(DH)=行号(取值范围1-25),(DL)=列号(取值范围1-80)(CL)=颜色 
;    DS:SI指向字符串的首地址 
show_str:
         mov ax,0b800h
         mov es,ax
         mov al,0A0h
         dec dh
         mul dh
         mov bx,ax
         mov al,2 
         dec dl
         mul dl
         mov di,ax
         mov al,cl
       s:mov ah,ds:[si]                                        
         mov ch,ah  ;判断是否是0字符
         mov cl,0
         jcxz return
         mov  es:[bx+di],ah
         mov  es:[bx+di+1],al
         add di,2
        inc si
        jmp short s
 return:
        ret
code ends
end start


在win-masm中编译运行,在显示出603795834
在debug中用G命令执行后是12666
正确结果应该是12666,可就是不知道为什么?
各位帮我看看,谢谢!
peterhui
[第1楼]   [ 回复时间:2008-06-07 21:12 ]   [引用]   [回复]   [ top ] 
荣誉值:24
信誉值:21
注册日期:2007-08-13 23:04
试了一下,运行没有问题啊
cairulong
[第2楼]   [ 回复时间:2008-06-07 22:26 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-04-27 16:45
没有问题吗?
我换了一台机运行结果是445788538
为什么会这样呀。头都大了。
peterhui
[第3楼]   [ 回复时间:2008-06-07 23:40 ]   [引用]   [回复]   [ top ] 
荣誉值:24
信誉值:21
注册日期:2007-08-13 23:04
再次试了,也一步步跟踪了,没发现什么问题,我想是不是你的编译器有问题啊
cairulong
[第4楼]   [ 回复时间:2008-06-08 20:11 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-04-27 16:45
感谢peterhui,peterhui你是用什么编译器?
到现在我也找不出什么问题。
peterhui
[第5楼]   [ 回复时间:2008-06-08 21:51 ]   [引用]   [回复]   [ top ] 
荣誉值:24
信誉值:21
注册日期:2007-08-13 23:04
我用的就是书上所说的微软masm5.0汇编编译器,你重新下载一个试试或我发给你也可以。不过我只是怀疑是编译器的问题,只能说是试试看能不能解决问题,如果还是不行,那就看能不能别的人帮到你了。
lower
[第6楼]   [ 回复时间:2008-06-10 17:51 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-06-10 17:45
在dtoc函数里面的这一行:exit0:pop cx 循环终止之后,仍然会有数据(或许是0)出栈,进入cx中,这样sp的指向就发生了变化,ret也就不能正确返回了。
修改之后,在s2:后面加上push cx,结果仍然有错误,但是和12666比较接近了,估计后面还有与栈相关的数据问题。
cairulong
[第7楼]   [ 回复时间:2008-06-10 20:57 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-04-27 16:45
出入栈没有问题,程序返回正常!在G命令执行显示结果是正常的。
lower
[第8楼]   [ 回复时间:2008-06-11 09:33 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-06-10 17:45
我看漏了,前面有将0入栈,所以出入栈没有问题。出入栈既然虽然没有问题,那么最后的结果也应该不会有问题,但是却出现了问题,那我估计就是出入栈的数据出现了问题。最开始dx没有初始化,导致dx中的值未知,调用divdw之后直接将dx中的值保留,于是就出现了数据错误,然而dx最初的值是和编译器有关的,我估计G命令中dx为0,所以才没有问题,然而编译器编译后执行时dx不一定为0,就有问题了。
 s0:mov cx,0Ah 改为
 s0:mov dx,0  ;将dx初始化
 mov cx,0Ah 

或者一开始在mov ax,12666之后就加入mov dx,0即可,编译执行就没有问题了。
另外,lz的程序很简练,让我受益匪浅。
cairulong
[第9楼]   [ 回复时间:2008-06-11 17:09 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-04-27 16:45
对呀,一直没有考虑到divdw的DX问题。
谢谢lower的帮忙!!lower的热心感动了我。
自己太粗心了,最近也没有时间管它。
我想用在课程设计1上没有问题了。
结贴!!!!!
zgl80438989
[第10楼]   [ 回复时间:2008-07-01 23:18 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-05-30 11:10
调试通过
 assume cs:code
  data segment
    db 10 dup (0)
  data ends
 code segment
start:mov ax,12666
      mov bx,data
      mov ds,bx
      mov si,0
      call dtoc
      mov dh,13
      mov dl,70
      mov cl,2
      call show_str
      mov ax,4c00h
      int 21h
 dtoc:
         mov bx,10
         mov di,0
     s0: div bx
         mov cx,ax
         add dx,30h
         push dx
         inc di
         jcxz ok1
         mov dx,0
         jmp short s0
     ok1:mov cx,di
       s2:pop ax
          mov ds:[si],al
          inc si
          loop s2
          mov si,0
          ret
show_str:
        push si
        push cx
        mov al,0a0h
        mov ah,0
        mul dh
        mov dh,0
        mov di,ax
        add di,dx
        mov ax,0b800h
        mov es,ax
        mov al,cl
     s1:mov cl,ds:[si]
        mov ch,0
        jcxz ok2
        mov es:[di],cl
        inc di
        mov cl,al
        mov es:[di],cl
        inc si
        inc di
        jmp short s1
   ok2: pop cx
        pop si
        ret
code ends
end start
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved