|
主题 : : 实验10 dtoc中逆向输出的解决方法 [待解决] |
回复[ 7次 ]
点击[ 446次 ] | |
|
|
|
|
[帖 主]
[ 发表时间: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 | | |
|
|
|
|
[第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 | | |
|
|
|
|
[第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 | | |
|
|
|
|
[第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型数据
楼主只用一个综合程序就行了,嘿嘿,比我的精简,学习了 | | |
|
|
|
|
[第4楼]
[ 回复时间:2010-01-04 10:26 ]
[引用]
[回复]
[ top ] | |
荣誉值:9
信誉值:0
注册日期:2009-10-18 04:41 |
哈哈,楼上的朋友分析的不错,我刚开始是放在后面的 可是后来我才发现有问题,其实也不用放在后面,直接多加一句就好了,的就是把这个数的高位也加进来让cx检查一下看是否为零.
我之前想的是一个数如果低位都为零了那么高位肯定除完了,没想到楼上说的这一点呵呵,,请大家注意
多谢指教 | | |
|
|
|
|
[第5楼]
[ 回复时间:2010-01-19 22:11 ]
[引用]
[回复]
[ top ] | |
荣誉值:2
信誉值:1
注册日期:2009-12-24 11:13 |
进来学习了,关于第三个我一直没有搞得很清楚,好好学习一下 | | |
|
|
|
|
[第6楼]
[ 回复时间:2010-01-20 14:18 ]
[引用]
[回复]
[ top ] | |
荣誉值:6
信誉值:0
注册日期:2009-12-18 19:53 |
add dx,30h
mov ds:[si],dx
当把所得到的余数加上30h后,既然是在后面的出栈时,才把值放入ds:[si]时,这里放进去是干嘛呢?请指教, | | |
|
|
|
|
[第7楼]
[ 回复时间:2010-01-20 22:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:3
信誉值:0
注册日期:2009-10-27 16:12 |
回楼上的
---------------------------------------------------------
add dx,30h
mov ds:[si],dx
这两条指令目的是把所得的余数加上30H,入栈
之所以现在就把余数加上30H再入栈,是为了出栈的时候不需要转换了,直接得到可显示的ASCII码
其实就像你说的,完全可以先把余数入栈,等到出栈的时候再转换,这一点可以自由选择 | | |
|