首页
社区
课程
招聘
[求助]王爽的《汇编语言》实验3的问题
2008-10-18 10:40 15419

[求助]王爽的《汇编语言》实验3的问题

2008-10-18 10:40
15419
assume       cs:codesg   
  codesg       segment   
          mov     ax,2000h   
          mov     ss,ax   
          mov     sp,0   
          add     sp,4   
          pop     ax------->debug跟踪到此时,出现:cpu遇到无效指令,选择“关闭”终止应用程序          pop     bx                                                                  
       push   ax                                                              
          push   bx                                                            
       pop     ax   
          pop     bx   
          mov     ax,4c00h   
          int     21h   
  codesg     ends   
  end   
   
  os:winxp     masm5.0   
  刚学汇编,请大家说说为什么。   
  谢谢

阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!

收藏
点赞0
打赏
分享
最新回复 (15)
雪    币: 247
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
chaostring 1 2008-10-18 12:08
2
0
Debug 了一下,没有问题。
上传的附件:
雪    币: 211
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
嗜血狂君 2008-10-18 12:48
3
0
我试了好多次啊,都提示:

C:\WINDOWS\system32\cmd.exe - debug t1.exe
NTVDM CPU 遇到无效的指令.
CS:0000 IP:0077 OP:f0 37 05 0e 02 选择"关闭"终止应用程序.

朋友帮忙给分析下,谢谢了
雪    币: 247
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
chaostring 1 2008-10-18 13:54
4
0
我也不知道了。要不你重新编译一下?因为程序本身是没有什么问题的。
雪    币: 347
活跃值: (25)
能力值: ( LV9,RANK:420 )
在线值:
发帖
回帖
粉丝
小子贼野 10 2008-10-18 14:17
5
0
我看不出来有什么错误,在我这里也可以编译通过的
雪    币: 207
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
athlor 2008-10-19 06:24
6
0
感觉16位汇编学了没啥实际应用价值啊.
直接学32位汇编吧.顺带连很多系统知识也可以一并了解.
调试可以用OD的.比debug方便很多,
雪    币: 206
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
caojianrui 2008-10-19 09:13
7
0
王爽老师汇编语言支持网站http://www.asmedu.net/里面有详细讨论.
这是我转抄的请参考:
问题1、TT单步执行 pop ax 时,出现 NTVDM CPU 遇到无效指令 对话框。为什么?如何解决?   
-----------------------------------------------------------------------------------------
在windows系列操作系统环境下,我们进入的cmd或command都是工作在保护模式下的DOS操作系统的虚拟机,在保护模式下,windows操作系统要对程序执行的优先权以及程序访问内存空间的权限和方式进行控制或者说限制,如果有违反这些限制规范的用户进程执行,那么windows的安全机制为了保证操作系统的正常运转,就要杀死这个进程,并提示错误信息。
在这里首先声明这里的pop ax指令是没有语法错误的,在DOS实模式下随时都有效可执行;但是它用在不合理的地方,就会出现逻辑错误(导致栈顶超界),这种逻辑错误实模式DOS操作系统是不予理睬的,它的安全机制相对薄弱,逻辑错误的出现要靠人来发现,排除。但是在保护模式下,进行push栈操作或pop栈操作时,一旦出现栈顶超界状况,即会被工作在这个模式下的操作系统(如windows系列的)得知,并进行相应处理。

找到产生非法操作的原因:栈顶超界;
避免栈顶超界状况的出现有两种:
1、把栈顶位置设置合理;
2、合理的使用栈操作指令push 和 pop 。

问题2、栈空间里没有内容,此时能弹堆栈?  
-----------------------------------------------------------------------------------------
首先说什么是栈空间,栈空间无非是一段由SS:SP指示的内存空间而已,一般情况下我们能够用栈操作指令访问它,当然,我们也可以用访问内存地址的任何一种合理方式访问这段空间。其次,我们说 栈空 表明的意思是:栈顶设置之初,我们没有栈操作的时候,这段空间的数据我们是未知的,所以通常也是没有用的,但是并不代表这时栈顶SS:SP所指向的内存字单元中没有数据!再有一点:无论是push还是pop操作,栈的操作在任何情况下都是有效的(但不一定在任何情况下都是合理的,对于不合理的栈操作正如问题 1 的回答中所讲,会有操作系统的干预。)

回到楼主的问题:

对于以上问题(栈顶没有处在0000偏移地址位置,一次栈操作不会发生栈超界,但为什么出现错误信息提示)的出现我是这样理解的:
这种情况出现在debug跟踪像楼上的朋友贴出来的那样的程序的时候,由于栈顶设置的位置接近一个内存段的开始位置,我们在使用debug的 T 命令进行单步跟踪,debug执行T命令的过程大体是:
1、设置控制程序执行的相关状态字(保证执行被加载程序的一条指令后,暂停程序后面语句的执行),执行权交给被加载程序;
2、执行被加载程序的当前指令,当然,紧接着的语句由于步骤 1 的设置不能获得执行,执行权就又交给了debug;
3、debug负责显示各寄存器状态及相关信息的子程序块执行:
   a、保存当前被加载程序的状态,即保存相关寄存器的状态等信息(保存位置:栈空间;实现方式:入栈操作);
   b、显示各寄存器的状态(a步骤后栈中的某些数据)及相关信息(下一条指令);
   c、恢复各寄存器状态(出栈操作),等待下一个debug命令的输入。
对于以上过程,稍加分析可知栈空间的位置(寄存器SS中的内容)在这个过程中是不能够也不允许发生变化的,所以a步骤中的栈操作也发生在被加载程序使用的栈空间内,这时,如果栈顶的位置离栈段开始位置较近且a步骤中栈操作的次数相对较多,就难免会发生栈顶超界现象了。
来源于Wednesday
修改方法:add sp,4改成add sp,天于6的数
个人认为debug 时引起中断要保存Flags,cs,ip三个寄存器的内容故要大于6.
雪    币: 211
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
嗜血狂君 2008-10-21 11:05
8
0
多谢楼上各位前辈的指导,尤其是caojianrui 说的很详细,了解了很多,以后有不懂得再来请教各位!
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
那年夏天 2008-10-21 17:22
9
0
这个是因为16位汇编对堆栈的空间的操作是由程序员来进行分配的,而你分配的堆栈空间不够大,产生了溢出而导致出错的,在写16位汇编的时候,要注意对堆栈的大小进行分配,貌似在32位汇编中,不会出现这样的错误
雪    币: 211
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
嗜血狂君 2008-10-22 14:18
10
0
请教这位朋友!我不明白,我的栈的空间怎摸会不够大呢???能详细的给我讲解一下吗??万分感谢
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
那年夏天 2008-10-22 14:27
11
0
7楼已经解释的够清楚了,而且我记得王爽老师的汇编书上也有写到堆栈是由程序员自己来进行划分的

对于以上过程,稍加分析可知栈空间的位置(寄存器SS中的内容)在这个过程中是不能够也不允许发生变化的,所以a步骤中的栈操作也发生在被加载程序使用的栈空间内,这时,如果栈顶的位置离栈段开始位置较近且a步骤中栈操作的次数相对较多,就难免会发生栈顶超界现象了。


楼主注意下这句话,然后再看看你的程序
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
那年夏天 2008-10-22 14:31
12
0
貌似也不能说是不够大,我也不大会描述

总之,是你动了不能动的地方,所以就出错了
雪    币: 211
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
嗜血狂君 2008-10-22 15:26
13
0
这个解释还算满意,我看书上说的也差不多就是这个原因,嘿嘿,谢谢你了
雪    币: 211
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
嗜血狂君 2008-10-22 15:36
14
0
不好意思  发重复了  删除
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
那年夏天 2008-10-22 23:33
15
0
呵呵,不用这么客气的

对比一下16位汇编和32位汇编你就能大致的理解了

我也不懂汇编,只是恰巧有看过这方面的文章,呵呵
雪    币: 223
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ifworld 2009-5-1 20:23
16
0
你把 add     sp,4   

改成  add     sp,10 试试 你的栈定义的太小了
游客
登录 | 注册 方可回帖
返回