. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->CALL和RET指令
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  实验10 dtoc中逆向输出的解决方法  [待解决] 回复[ 7次 ]   点击[ 446次 ]  
release_lag
[帖 主]   [ 发表时间:2009-12-18 14:56 ]   [引用]   [回复]   [ top ] 
荣誉值:3
信誉值:0
注册日期:2009-10-27 16:12
先看代码
    dtoc:push cx
         push dx
         push ax
         push si

    core:mov cx,10
         mov dx,0
         div cx

         add dx,30h
         mov ds:[si],dx
         push dx               ;在这里把dx入栈,DX占两个字节
         mov cx,ax
         jcxz ok1
         inc si
         jmp short core

     ok1:inc si               ;设置循环次数,注意,循环次数等于si+1
         mov cx,si             
         mov si,0
       s:pop ds:[si]          ;数据出栈,前一个数的高位节字会被后一个数据的低位字节覆盖
         
         inc si
         loop s

         pop si
         pop ax
         pop dx
         pop cx
         ret
yiyn
[第1楼]   [ 回复时间:2009-12-25 17:40 ]   [引用]   [回复]   [ top ] 
荣誉值:9
信誉值:0
注册日期:2009-10-18 04:41
呵呵,在给个思路,用栈中的一段来操作,如栈定义的为128 为了怕出错,我们取sp为64开始,
用一个寄存器保存sp之前的值
mov si,sp
mov sp,64
我们记到首地址是64就好了,有什么用了,用来给cx
也就是说出栈的时候用sub cx,sp这时你不用管他的地址是什么,到栈出完之后cx一定为零,也就是说们就可以直接用sub cx,sp这句来为jcxz的条件退出显示
下面是我的做法:
         changeshow:push si
                    push cx
                    push bx
                    push dx
                    push bp
                 mov si,sp
                 mov sp,64
            smain:mov cx,ax
                  jcxz showOK 叛断是否要退出除法(只看ax的原因是因为ax为低位,低位没了高位自然除完)
                  push ax
                  mov ax,dx
                  mov dx,0
                  mov cx,10
                  div cx
                  mov bx,ax
                  pop ax
                  div cx
                  add dx,30h
                  mov dh,2   入栈前把字体色设直为录色存入DX的高位,以便出栈直接用
                  push dx
                  mov dx,bx
                  jmp short smain  以上完成了除法溢出的运算,并入栈
           showok:pop es:[bp] 直接写入显存,注意这里bp要在主程序里面处理(写入显存的地址)
                  add bp,2 显存地址自动加2
                  mov cx,64 cx得到栈的最顶地址
                  sub cx,sp 确定有没有输完输完后CX为零
                  jcxz exitshow 为零后退出
                  jmp short showok 不为零接着写入显存
        exitshow:mov sp,si
                 pop bp
                 pop dx
                 pop bx
                 pop cx
                 pop si
                 ret
release_lag
[第2楼]   [ 回复时间:2009-12-26 13:26 ]   [引用]   [回复]   [ top ] 
荣誉值:3
信誉值:0
注册日期:2009-10-27 16:12
呵呵,为了分析楼上的思想,我把每段后面都加了注释。。。楼主把dtoc和show_str,两个子程序综合在一起了,而且用sub cx,sp 来判断余数是否复制完成,有意思,呵呵
         changeshow:push si 
                    push cx 
                    push bx 
                    push dx 
                    push bp 
                 mov si,sp             ;栈顶地址赋值给SI
                 mov sp,64             ;栈顶地址赋值为64
            smain:mov cx,ax            ;数据低16位传递给cx
                  jcxz showOK          ;检查cx是否为0
                  push ax              ;数据低16位入栈,(sp)=62
                  mov ax,dx            ;数据高16位传递给ax
                  mov dx,0             ;dx赋值为0,先做高位除法
                  mov cx,10            ;除数为10
                  div cx               ;执行DIV后的结果是:ax为商,dx为余数
                  mov bx,ax            ;把商传递给bx
                  pop ax               ;数据低16位出栈(sp)=64
                  div cx               ;再做除法.DIV之后的结果就是:ax为商,dx为余数
                  add dx,30h           ;余数加30H,
                  mov dh,2             
                  push dx              ;把颜色和余数一起入栈,(sp)=62
                  mov dx,bx            ;把高位商赋给dx
                  jmp short smain      ;跳转至smain处继续执行
           showok:pop es:[bp]          ;除到商为零时,跳至此处,把余数出栈
                  add bp,2             
                  mov cx,64            
                  sub cx,sp            ;检查商是否出栈完毕(((直到cx为0)))
                  jcxz exitshow        
                  jmp short showok 
        exitshow:mov sp,si             ;恢复栈顶地址
                 pop bp 
                 pop dx 
                 pop bx 
                 pop cx 
                 pop si 
                 ret
release_lag
[第3楼]   [ 回复时间:2009-12-26 13:48 ]   [引用]   [回复]   [ top ] 
荣誉值:3
信誉值:0
注册日期:2009-10-27 16:12
后来才看到,这段程序是有问题的,mov cx,ax 
                            jcxz showOK

这两句应该放到后面,因为如果ax,一开始就是0的话,那楼主的程序就有问题了,
打个比方如果有一个DW型数据是: F 0000H,这里的ax就是0了。。。。
当然课程1里面的数据没有(ax)=0,所以完全可以得到正确答案,我在课程设计1中用dtoc_dw来转DW型数据,用dtoc来转Word型数据
楼主只用一个综合程序就行了,嘿嘿,比我的精简,学习了
yiyn
[第4楼]   [ 回复时间:2010-01-04 10:26 ]   [引用]   [回复]   [ top ] 
荣誉值:9
信誉值:0
注册日期:2009-10-18 04:41
哈哈,楼上的朋友分析的不错,我刚开始是放在后面的 可是后来我才发现有问题,其实也不用放在后面,直接多加一句就好了,的就是把这个数的高位也加进来让cx检查一下看是否为零.
我之前想的是一个数如果低位都为零了那么高位肯定除完了,没想到楼上说的这一点呵呵,,请大家注意
多谢指教
ldllihuanfa
[第5楼]   [ 回复时间:2010-01-19 22:11 ]   [引用]   [回复]   [ top ] 
荣誉值:2
信誉值:1
注册日期:2009-12-24 11:13
进来学习了,关于第三个我一直没有搞得很清楚,好好学习一下
ldlihuanfa
[第6楼]   [ 回复时间:2010-01-20 14:18 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:0
注册日期:2009-12-18 19:53
add dx,30h 
         mov ds:[si],dx 
当把所得到的余数加上30h后,既然是在后面的出栈时,才把值放入ds:[si]时,这里放进去是干嘛呢?请指教,
release_lag
[第7楼]   [ 回复时间:2010-01-20 22:12 ]   [引用]   [回复]   [ top ] 
荣誉值:3
信誉值:0
注册日期:2009-10-27 16:12
回楼上的
---------------------------------------------------------
add dx,30h
mov ds:[si],dx
这两条指令目的是把所得的余数加上30H,入栈
之所以现在就把余数加上30H再入栈,是为了出栈的时候不需要转换了,直接得到可显示的ASCII码


其实就像你说的,完全可以先把余数入栈,等到出栈的时候再转换,这一点可以自由选择
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved