. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->寄存器(内存访问)
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  为什么--除了段寄存器外的所有寄存器都能把数据直接MOV,而段寄存器不能?  [待解决] 回复[ 2次 ]   点击[ 292次 ]  
xinyuan365
[帖 主]   [ 发表时间:2008-12-23 10:56 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-12-23 10:46
我在论坛上也做了回答,但不对。希望大家都帮忙想想。
http://www.bodaren.cn/viewthread.php?tid=1048&page=1&extra=#pid1688
coco
[第1楼]   [ 回复时间:2008-12-25 23:33 ]   [引用]   [回复]   [ top ] 
荣誉值:12
信誉值:0
注册日期:2007-11-13 09:24
先把上文链接的内容拷贝过来,方便大家阅读
-------------我是分割线-------------
对实验3第二个问题的深入分析
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

系统环境:winxp+masm5.0

问题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(详细内容,看这里)

刚才试了下,如果把mov sp,4 改为mov sp,6果真能顺利执行了。而且换了台电脑,发现在masm下也可以正常执行debug了。
mouselove
[第2楼]   [ 回复时间:2009-01-06 11:25 ]   [引用]   [回复]   [ top ] 
荣誉值:13
信誉值:0
注册日期:2008-03-09 16:31
这么看多麻烦,楼主在汇编网的博客发不更方便 :-)
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved