汇编网首页登录博客注册
rsice的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
学习动态
最新留言
好友圈
文章收藏
友情链接

[2008-04-07 23:09] 我快崩溃了!求救!实验10子程序3:显示字符串我始终不成功,同学们帮忙看看!

图片载入中
我先说说情况:这个程序可以编译通过,但是执行错误。错误的语句我在注释中表出来,先不说我的方法好不好,我也知道方法太烦,但我想先解决错误。
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   bx,data
        mov   ds,bx
        mov   si,0
        mov   ax,stack
        mov   ss,ax
        mov   sp,16
        mov   ax,12666
        mov   dx,0
        call  dtoc
                      
        mov   dh,8
        mov   dl,3
        mov   cl,2                          
        call  show_str

                      
        mov   ax,4c00h
        int   21h
              
dtoc:   mov   bx,0  ;因不知道数字有几位,我预先压入一个0作为结束标记
         push  bx
                          
        mov   bx,0ah
s1:     div   bx
        push  dx        ;dx存放余数,压栈备用
        mov   dx,0      ;dx清零,准备循环--问题就出在这一句,前面几次循环都正常,到了倒数第2次循环做完,也就是ax=1,dx=2的时候,准备再次赋值做最后一次除法的时候,执行mov dx,0这句出错,我想破脑壳想不出来这句为什么会错!请大家帮忙诊断一下,我现在真的很痛苦!                  
        mov   cx,ax     ;ax是商放入cx以判断是否为0
        jcxz  transform        ;如果ax为0了,cx=0,就跳走开始处理
        jmp   s1
                                       
transform: pop   cx       ;依次从堆栈中出栈到cx,顺序应该是1,2,6,6,6,0
             jcxz  ok       ;如果cx=0,说明已经取完,也就处理完了,可以结束dtoc子程序了
           add   cx,30h   ;取出后加30h,转化为字符,放入cx中
           mov   [si],cx  ;放到ds:[si]中
            add   si,2     ;因为是字长,所以si要加2
          jmp   transform;跳到标记处继续处理下一个

ok:           ret            ;到这里,堆栈里的东西都已经出栈了,只剩下ip了,应该跳到mov dh,8那句了
              

show_str:     mov ch,0
              push cx
              mov ax,0           
              mov al,dh
              mov bl,0ah
              mul bl
              mov bx,0b800h          
              add bx,ax
              mov es,bx              ;定位字符串起始行的位置

                mov ax,0
              mov al,dl
              mov bh,0
              mov bl,2
              mul bl
              mov di,ax              ;定位字串起始列的位置
     
                pop ax              ;ax放颜色参数
s2:           mov cl,ds:[si]        ;以si作为字符串首地址,送入cl
              jcxz over              ;处理完毕就结束子程序,否则处理
                mov es:[di],cl        ;送入目标位置
                mov es:[di+1],al      ;把颜色参数送入
                add si,2
              add di,2
              jmp short s2
     
over:         ret                        

code ends
end start
评论次数(15)  |  浏览次数(1049)  |  类型(汇编作业) |  收藏此文  | 

[  游客   发表于  2008-04-08 12:11  ]

show_str中 

1、mov bl,0ah ;为什么赋值为 0ah ,应该为 160。

2、
mov bx,0b800h           
add bx,ax 
mov es,bx              ;定位字符串起始行的位置 

将行偏移添加到了段地址中?!应该把行、列偏移都放在偏移地址寄存器di中。

3、mov bh,0 ;这句没意义

[  游客   发表于  2008-04-08 12:15  ]

showstr中
si的初始值是主程序中的 mov si,0之后的 0 吗?

功能子程序dtoc中应该添加保护现场和恢复现场语句序列!

[  starrynight   发表于  2008-04-08 12:17  ]

恩,问题按照上面的能够解决。
回帖可信度=100
呵呵

[  rsice   发表于  2008-04-08 12:20  ]

谢谢评论首先,
1、mov bl,0ah ;为什么赋值为 0ah ,应该为 160。 
2、 
mov bx,0b800h            
add bx,ax  
mov es,bx              ;定位字符串起始行的位置  

将行偏移添加到了段地址中?!应该把行、列偏移都放在偏移地址寄存器di中。
答:是这样的,我是把行、列分开来出来的,没有作为一个数据处理。
showstr中 
si的初始值是主程序中的 mov si,0之后的 0 吗? 

功能子程序dtoc中应该添加保护现场和恢复现场语句序列!
答:确实没有保护现场,我觉得可能下面的处理不会对寄存器有影响,所以没保存。

另外,我的show_str子程序是完成了的,问题是出在dtoc子程序中,能否请你帮忙调试一下!

[  wdm   发表于  2008-04-08 15:07  ]

我觉得可能下面的处理不会对寄存器有影响,所以没保存
===================
子程序中非必要的返回参数或特殊的入口参数外,用到的寄存器一定要保存。

题是出在dtoc子程序中,能否请你帮忙调试一下!
==========
我觉得这个还是自己用debug来调试吧。别人的帮助应该点到为之,自己通过第10章后,将是一个质的跨越。
debug调试不要嫌麻烦,那才是你进步的道路。

[  wdm   发表于  2008-04-08 15:22  ]

AX=000C  BX=000A  CX=000C  DX=0000  SP=0006  BP=0000  SI=0000  DI=0000
DS=1405  ES=13F5  SS=1406  CS=1407  IP=002E   NV UP EI PL NZ NA PO NC
1407:002E F7F3          DIV     BX
-t

AX=0001  BX=000A  CX=000C  DX=0002  SP=0006  BP=0000  SI=0000  DI=0000
DS=1405  ES=13F5  SS=1406  CS=1407  IP=0030   NV UP EI PL NZ NA PO NC
1407:0030 52            PUSH    DX
-t

AX=0001  BX=000A  CX=000C  DX=0002  SP=0004  BP=0000  SI=0000  DI=0000
DS=1405  ES=13F5  SS=1406  CS=1407  IP=0031   NV UP EI PL NZ NA PO NC
1407:0031 BA0000        MOV     DX,0000
-t

博主看看这里的sp的值,mov dx,0000后的T命令的时候,你的sp只剩下4了,记得前面运到过由于sp值过小,在debug下的T单步跟踪时候出错的情况码?就是这里了。所以,这不是你程序没有正确运行的根本。

[  wdm   发表于  2008-04-08 15:24  ]

建议楼主重新整理一下思路和程序,函数要一个一个的写,一个一个的调试,不要攒堆啊。

[  rsice   发表于  2008-04-08 19:07  ]

谢谢wdm的指点,我花了很长时间,绝对没有怕麻烦,要不是兴趣所在,我哪还有这个动力,放弃工作之余的几乎所有时间来学习汇编啊,我调试了很多遍,只是实在想不通啊,
“博主看看这里的sp的值,mov dx,0000后的T命令的时候,你的sp只剩下4了,记得前面运到过由于sp值过小,在debug下的T单步跟踪时候出错的情况码?就是这里了。所以,这不是你程序没有正确运行的根本。”
我马上实验一下,看看是不是这个原因,我想到过会不会是栈顶超界,但是看看堆栈够用的,所以没在意,我实验以后在报告,先谢过啊!

[  xiaochong   发表于  2008-04-08 19:54  ]

呵呵,看来来晚了,祝博主早日将此程序完成!

努力+坚持=必胜!

[  wuerlang   发表于  2008-04-08 21:07  ]

支持博主!

[  游客   发表于  2008-04-08 21:17  ]

将行偏移添加到了段地址中?!应该把行、列偏移都放在偏移地址寄存器di中。 
答:是这样的,我是把行、列分开来出来的,没有作为一个数据处理。
---------------------
分开处理可以,单是要知道 es是段寄存器,向es中加1,在物理地址就会影响 10h !!!

[  游客   发表于  2008-04-08 21:18  ]

功能子程序dtoc中应该添加保护现场和恢复现场语句序列! 
答:确实没有保护现场,我觉得可能下面的处理不会对寄存器有影响,所以没保存。 
-------------------------
实际影响了吗?
计算机没有可能!!!

[  rsice   发表于  2008-04-08 23:12  ]

wdm:博主看看这里的sp的值,mov dx,0000后的T命令的时候,你的sp只剩下4了,记得前面运到过由于sp值过小,在debug下的T单步跟踪时候出错的情况码?就是这里了。所以,这是你程序没有正确运行的根本。
   感谢wdm的指点!确实如此,我按照你说的扩大了堆栈长度,结果确实不出错了!你说的这个情况我真的一点也不知道!书里哪里说过吗?还有没什么会出现这个情况?按理说,堆栈不是还有2个字的位置吗?

[  hantangtianxia   发表于  2008-04-08 23:17  ]

debug跟踪的问题

如果直接运行或debug g命令 执行,不会出问题

[  wdm   发表于  2008-04-09 14:30  ]

书里哪里说过吗?还有没什么会出现这个情况?按理说,堆栈不是还有2个字的位置吗?
=====================
书中直接提到的地方你还没有学到,在后面的中断章节。不过,从第三章实验任务的最后一个题目(70页),那个图3.19的思考题,就是提示你了这个问题的,难道博主没有思考过?其实很多人都不会想明白,但是,不明白你就得来交流,那么今天这个问题就不至于困扰你这么久了。
一定要做到:每章节的知识点和思考题都有了明确的了解,在向下学习。你的这个经历就是一个好的反面教材啊。呵呵呵,后来者警戒吧。

 
 请输入验证码  (提示:点击验证码输入框,以获取验证码