|
主题 : : 奇怪问题,请来指导一下,在线等,哈哈,谢谢了! [已解决] |
回复[ 6次 ]
点击[ 500次 ] | |
|
|
|
|
[帖 主]
[ 发表时间:2008-11-06 10:26 ]
[引用]
[回复]
[ top ] | |
荣誉值:6
信誉值:6
注册日期:2008-10-15 11:11 |
assume cs:code
data segment
db 'Welcome to masm!',0
data ends
stack segment
db 16 dup(0)
stack ends
code segment
start: mov dh,8
mov dl,3
mov cl,5
mov ax,data
mov ds,ax
mov si,0
call show_str
mov ax,4c00h
int 21h
show_str:
mov ax,stack
mov ss,ax
mov sp,16
push dx 行和列的参数入栈
push cx 颜色的参数入栈
push si 把主程序的寄存器入栈
mov bp,sp bp指向栈顶
mov ax,0
mov al,160
mul byte ptr ss:[bp+5] 行地址大小
mov bx,ax 把计算好的行地址大小存入BX寄存器
mov ah,0
mov al,2
mul byte ptr ss:[bp+4] 列地址大小
add ax,bx
mov di,ax 把行和列地址的偏移地址存入DI寄存器
mov ax,0b800h
mov es,ax 显存地址
mov si,0
cycle: mov ch,0
mov cl,ds:[si] 取字符
jcxz ok
mov es:[di],cl 送到显存
mov ch,ss:[bp+2] 取颜色
mov es:[di+1],ch 送显存
inc si
add di,2 循环进行
jmp short cycle
ok: pop si 当最后一个字符为“0”的时候返回
pop cx 并返回相关的寄存器
pop dx
ret
code ends
end start
以上是我的源程序,名字叫prac10,故执行程序为prac10.exe。
现象1:用DEBUG调试,载入程序,然后用 第一次g cd21命令,可以显示;还是在DEBUG界面,第二次用
g cd21命令,不能正常显示?我想这是正常的,因为程序执行过一次,一定要重新载入才可以执行,但不是很确定自己的解释对不对?
现象2:在CMD界面,直接输入prac10.exe,显示NTVDM CPU遇到无效的指令,CS:059a,ip:97c8,0P:65 63 69 66 69 选择“关闭”终止应用程序。
对现象2的简单调试的结果:一定要先用DEBUG载入程序,然后才能直接在CMD界面下使用parc10.exe;并且只能输入prac10.exe 一次,如果再次prac10.exe会出现现象2的情况。
以上2个现象请帮忙解释一下,特别是现象2,是我程序出错了?还是?谢谢,各位了! | | |
|
|
|
|
[第1楼]
[ 回复时间:2008-11-06 10:46 ]
[引用]
[回复]
[ top ] | |
荣誉值:472
信誉值:12
注册日期:2007-10-16 15:34 |
|
|
|
|
|
[第2楼]
[ 回复时间:2008-11-06 10:47 ]
[引用]
[回复]
[ top ] | |
荣誉值:152
信誉值:3
注册日期:2008-01-24 21:26 |
现象1:用DEBUG调试,载入程序,然后用 第一次g cd21命令,可以显示;还是在DEBUG界面,第二次用
g cd21命令,不能正常显示?我想这是正常的,因为程序执行过一次,一定要重新载入才可以执行,但不是很确定自己的解释对不对?
--------------------------------------
g 命令是从当前地址执行到你给定的地址出。所以,第一次执行后,当前地址已经不再是程序的起始地址了,所以,在进行g命令就有问题了。 | | |
|
|
|
|
[第3楼]
[ 回复时间:2008-11-06 10:55 ]
[引用]
[回复]
[ top ] | |
荣誉值:152
信誉值:3
注册日期:2008-01-24 21:26 |
对现象2的简单调试的结果:一定要先用DEBUG载入程序,然后才能直接在CMD界面下使用parc10.exe;并且只能输入prac10.exe 一次,如果再次prac10.exe会出现现象2的情况。
------------------------
你的程序直接运行有问题,说明程序有错误的地方。mouse已经指出了,就是定位栈内数据造成的。call指令要push cs ,push ip,这时候用到的是默认的栈,而进入你的子程序后,你对当前栈进行了更改,之前call指令存cs,ip的栈就不是你指定的这个栈了,而在子程序结束后的ret是从当前栈中取数据重新赋值cs,ip的,那么就造成了子程序退出的时候cs,ip的值就不是你call的时候保存的cs,ip的值了,那么指向的指令也将是不可预知的,所以,运行错误很正常。
栈操作的时候一定要多个心眼。 | | |
|
|
|
|
[第4楼]
[ 回复时间:2008-11-06 10:57 ]
[引用]
[回复]
[ top ] | |
荣誉值:152
信誉值:3
注册日期:2008-01-24 21:26 |
mouse的方法能够解决你的问题,还有一个方法就是在修改ss之前push ss,在子程序ret指令之前在pop ss,这样就能保证你子程序的正确进入和退出了。
注意程序指令的定位,这在debug调试的时候是一个很重要的信息。 | | |
|
|
|
|
[第5楼]
[ 回复时间:2008-11-06 18:58 ]
[引用]
[回复]
[ top ] | |
荣誉值:6
信誉值:6
注册日期:2008-10-15 11:11 |
呵呵,mouse,早上的时候没有看到。。。!THANK YOU,mouse and crazyman! | | |
|
|
|
|
[第6楼]
[ 回复时间:2008-11-06 18:59 ]
[引用]
[回复]
[ top ] | |
荣誉值:6
信誉值:6
注册日期:2008-10-15 11:11 |
此贴由 贴主 于 [ 2008-11-06 18:59 ] 结贴。 结贴原因:问题已解决 | | |