. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->寄存器(内存访问)
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  第三章最后一个任务整不明白  [待解决] 回复[ 25次 ]   点击[ 2525次 ]  
helloworld
[帖 主]   [ 发表时间:2007-10-25 11:21 ]   [引用]   [回复]   [ top ] 
荣誉值:10
信誉值:6
注册日期:2007-10-20 14:34
0B07:0100 mov ax,2000
0B07:0103 mov ss,ax
0B07:0105 mov sp,10 
0B07:0108 mov ax,3123 
0B07:010B push ax
0B07:010C mov ax,3366
0B07:010F push ax 

实验问我20000H---2000FH的数据为什么会改变,那这不明摆着代码将栈段设为20000H-2000FH这个范围,push以后,肯定是将ax的数据压进这个段里的,那所以就变了嘛,但我不知道他怎么把cs:ip的数据压进去了,而不是将3123压进去?
fishboy
[第1楼]   [ 回复时间:2007-10-25 12:16 ]   [引用]   [回复]   [ top ] 
荣誉值:283
信誉值:0
注册日期:2007-06-26 11:42
楼主问的问题就是这道题目的意图啊!呵呵
好好考虑一下,栈里的数据是怎么不合你意的!变,必然有原因,这才是本题考验的重点。
xuanjinghua
[第2楼]   [ 回复时间:2007-10-26 16:45 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2007-10-22 21:04
因为用T指令进行调试时,会产生中断。而为了保护现场,CPU则先将标志寄存器进栈、再把当前CS的值进栈,最后将IP的值进栈!
    但是我用Debug调试过,怎么每次都是在Ip值前面留一个字,然后在前面的是第一次设置ax中的数值,怎么不会是其他的bx,cx之类的值呢?
    期待解答!!
xuanjinghua
[第3楼]   [ 回复时间:2007-10-27 09:34 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2007-10-22 21:04
搞错了!请把我的回复删除掉吧!
shanguianti
[第4楼]   [ 回复时间:2007-11-02 09:01 ]   [引用]   [回复]   [ top ] 
荣誉值:19
信誉值:0
注册日期:2007-10-31 16:24
昨天晚上没有弄明白,今天早晨又debug了一次。个人理解是这样的:栈空间是16个字节,用0~15表示,第一个push之前,先把一个值(这个值我也没有弄明白是什么)暂存在14~15两个字节里,接着把CS、IP送入10~13两个字节,再把ax的内容暂存在6~7两个字节里,第一个push之后,ax送入14、15两个字节里,刚才暂存的数字向上移动两个字节,并且IP的内容也变为CS:IP所指向的下一条指令的IP。第二个push同上,除了向上移动两个字节和IP改变外,就是把ax的内容也改变。
但是为什么会是这样呢?是不是在栈操作之前首先要保存现场的一些东西,操作完毕后还要恢复现场呢?也许只有随着学习的深入才能完全理解。
cat442
[第5楼]   [ 回复时间:2007-11-02 10:04 ]   [引用]   [回复]   [ top ] 
荣誉值:16
信誉值:6
注册日期:2007-06-26 16:56
支持楼上!

独立思考,独立实践,坚持下去,知道把问题搞清楚。

在方法上可以采取点策略,8086 cpu 寄存器就那么14个,大家都来试试,看看到底都是什么?
101319007
[第6楼]   [ 回复时间:2008-02-13 15:18 ]   [引用]   [回复]   [ top ] 
荣誉值:3
信誉值:0
注册日期:2007-08-07 13:15
注意看书上的图片,cs,ds,ss中的值都相同
huige
[第7楼]   [ 回复时间:2008-04-30 23:05 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-03-15 23:01
回复二楼:
我用debug分别令bx,cx,dx,bp,si,di,ds,es取得不同的值
最后发现ip前面的那个字是bp的值,后来又改变了bp的值(用r bp直接改的),然后查看栈中的内容,并没变化。
但是执行了push指令后,再来查看发现那个位置改变了(和bp一致)。但是标志寄存器不明白是什么呵呵,还有ax之前还有很多空间为0,不知道前面还有哪些寄存器的值被临时存放在了栈中。
jnwz159
[第8楼]   [ 回复时间:2008-05-13 21:02 ]   [引用]   [回复]   [ top ] 
荣誉值:3
信誉值:0
注册日期:2008-03-27 16:25
这是中断的原因。cpu调用中断例程的时候,会发生中断过程,这个过程会利用当前栈空间临时存放cpu运行的现场状态数据,比如说cs,ip等。而你在debug下的T命令就是一个中断例程。所以,就会出现你看到的现象了。 


T   就是个单步中断, 而8086对任何一个中断的处理都是一样的: 
1.标志寄存器入栈保存:sp<-sp-2,ss:[sp]<-flags 
2.禁止新的可屏蔽中断和但不中断,:if=tf<-0 
3.断点地址入栈保存sp<-sp-2,ss:[sp]<-cs:ip ;sp<-sp-2,ss:[sp]<-ip(注:高地址要存高位,低地址存地位) 
4.读取中断服务程序的起始地址:ip<-[n*4],cs<-[n*4+2](乘4是因为中断服务程序存放在内存0~3FFH地址内,高2为ip,低2为cs,4字节) 
所以,系统执行到第三步操作的时候,对应一下这个题里面d命令后面的那些数就明白了,六个状态标志,全是0(即6对0),ss,sp,cs,ip,就是显示出来的数了,至于最后那两个数是什么暂时没调出来,还请高手继续探索
(第一段是引用的另一个帖子高手的回答,下面是自己的认识)
hualongmian
[第9楼]   [ 回复时间:2008-05-17 14:58 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:0
注册日期:2008-05-13 20:29
紧挨着栈顶元素上面的两个单元。我用U命令验证了一下,书上的9D是POPF、05是AX,我在我机器上用DEBUG显示的是8f 06 用U看到的是8f060000 pop [0000]
不知道是什么意思哦。
norwolfli
[第10楼]   [ 回复时间:2008-05-30 09:25 ]   [引用]   [回复]   [ top ] 
荣誉值:2
信誉值:2
注册日期:2008-05-15 17:49
不太懂啊,刚学到这。看了上面的回复,了解了一些。

就是发生了“中断”,要“保护现场”。类似于其他语言中,一个方法调用另一个方法时执行的步骤。
leefox
[第11楼]   [ 回复时间:2008-05-31 23:31 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-01-21 11:43
回复:[贴 主]
------------------
通过改变寄存器的值来测试,发现T命令"保护现场"的经过是:
先是标志寄存器入栈
接着CS寄存器入栈
接着IP寄存器入栈
接着是BP寄存器入栈
最着是AX寄存器入栈

至于为什么是这样入栈,我不清楚,请高手回答!
dongxf
[第12楼]   [ 回复时间:2008-06-21 00:45 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:2
注册日期:2008-06-17 13:34
其实执行完mov ss,ax mov sp,10, 还没有执行到push ax, 2000:0 - 2000:f的内容就变了,所以和push没关系,和那个什么T中断有关,我也不懂,也许学到后面就懂了
usingnamespacestd
[第13楼]   [ 回复时间:2008-08-22 18:28 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-01-03 14:54
是啊,push还没执行呢,我承认我的悟性不好,o(∩_∩)o...另外,定义一个栈段,要不要初始化啊?
findfullmoon
[第14楼]   [ 回复时间:2008-08-28 22:27 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-08-22 13:31
我覺得大家想得都蠻強的。。
不過老師寫這本書 似乎是針對初學匯編並使用這本書來入門的同學吧。
書上說“如果在這裡就正確回答了問題,那麼要恭喜讀者有很好的悟性”。
如果是中斷之類的東西,我覺得讓人無從可悟。。。。。真要是學都沒學過就悟出來了。。真的蠻天才的。

從語句上來看
0B07:0100 mov ax,2000 
0B07:0103 mov ss,ax 
0B07:0105 mov sp,10  
0B07:0108 mov ax,3123 
只執行到了這裡。連push都沒有執行。

如果老師問到我,我也只能回答:不在棧中。
因為如果繼續執行語句就會發現push ax就會開始起作用並在內存中填入預期的數據。
所以只能判斷出,在push前的數據改變,與語句中的push語句沒什麼關係。。。

另外一旦push語句觸發的內存修改就不會再出現變化。我只能理解這是系統或者debug程序安排使用內存的方法。
因為我在不同版本的dos間使用不同版本的debug程序(ms-dos freedos rd-dos及所附帶的不同版本的debug程序),並沒有完全得到關於那個寄存器入棧的現象(也可能是我的手工輸入有誤吧。)。

希望有標準答案的達人 進來發個答案,好讓我等解惑。先謝謝了。
754754563
[第15楼]   [ 回复时间:2008-10-05 22:03 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-09-24 05:59
答:因为用T指令进行调试时,会产生中断。而为了保护现场,CPU则先将标志寄存器进栈、再把当前CS的值进栈,最后将IP的值进栈。
327451977
[第16楼]   [ 回复时间:2008-12-02 23:03 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-11-14 12:24
把第一个指令执行之后,内存中的内容变成了:

2000:0000    00 00 00 00 00 20 00 00-03 01 80 13 E4 0D 23 31   .......

其中E4 0D 应该是标志寄存器的内容,但是具体是哪个标志寄存器呢?
80 13应该是cs的内容,01 03 应该是ip的内容,但是,接下来的20 00 00 三组数是谁的内容呢?
请达人指教!!
struts8
[第17楼]   [ 回复时间:2008-12-10 21:43 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-12-06 21:24
不管了,继续看下一章,现在看来还不是天才,希望看完下面的内容再变成天才吧,哈哈!
tianyanly1984
[第18楼]   [ 回复时间:2008-12-15 07:45 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:4
注册日期:2008-12-12 00:18
据个人分析,单步跟踪,发现变化始于对sp赋值后,而且后面每执行一步都有相应变化,心想变化的东西肯定是记录的栈顶元素的位置信息,于是继续跟踪,果然理出头绪发现其规律为:

         前面没用到的字节位都为00+ax+bp+ip+cs+未知数据

中间的bp是试出来的,我开始还以为是cx,但给cx赋了一个值后测试并不是如此,然后凭直觉又试了si、bp,测试结果就是bp,但后面那个“0d 8a",也就是我说的未知数据,不知道是什么意思?(不同机子执行都不固定,所以被我称作未知数据)
有没有人研究出来后面这两个字节位或者说字型数据是什么含义,其它的数据目前我至少已经找到了一个固定的规律了,希望我的领悟能对14楼有所帮助.
b2311057
[第19楼]   [ 回复时间:2008-12-25 13:32 ]   [引用]   [回复]   [ top ] 
荣誉值:1
信誉值:0
注册日期:2008-12-16 07:53
第二个题我先看也是比较迷惑,在论坛上逛了一下,看见是这个解释:
------------------
通过改变寄存器的值来测试,发现T命令"保护现场"的经过是:
先是标志寄存器入栈
接着CS寄存器入栈
接着IP寄存器入栈
接着是BP寄存器入栈
最着是AX寄存器入栈

至于为什么是这样入栈,我不清楚,请高手回答!
------------------

但是我觉得既然我们没有指定栈的大小也无法指定栈的大小
我们指定的SS:SP为2000H:000H到2000H:000FH也只是我们心里想法
计算机并不知道这个空间我们已经预定了。
那么在没有任何PUSH的时候,SS:SP指向的栈大小是空的,那么计算机
就可以使用任何位置存放临时数据,只有栈内存放数据后,栈才会变大
CPU就将原来占用的位置腾出来给栈使用。
后面我接下来运行后面的两个PUSH AX命令可以看见
栈就像气球一样在放进去东西后自动膨胀,数据自动左移位
使用POP AX和POP BX后又会自动收缩,证实了我的想法。
bpswind
[第20楼]   [ 回复时间:2009-02-11 00:33 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-02-09 00:52
不错楼上的 正解! 因为虽然我们意识中是规定了 ss:sp 指2000H:000H到2000H:000FH 当然了电脑只认识ss:sp !里面的数据是否空白呢我们没和电脑说(也就是对他没有初始化)!希望我的理解能给楼主来点新想法 呵呵
jinxin
[第21楼]   [ 回复时间:2009-03-12 20:32 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-03-10 22:48
关于这个问题我也没看明白,按大家说的t是执行了push保护现场,那sp怎么没有变化?是不是t程序执行后,把sp又还原了?
advancedprogrammer
[第22楼]   [ 回复时间:2009-06-22 08:46 ]   [引用]   [回复]   [ top ] 
荣誉值:2
信誉值:3
注册日期:2009-06-08 15:13
实验问我20000H---2000FH的数据为什么会改变,那这不明摆着代码将栈段设为20000H-2000FH这个范围,push以后,肯定是将ax的数据压进这个段里的,那所以就变了嘛,但我不知道他怎么把cs:ip的数据压进去了,而不是将3123压进去?
------------------
回复:
实验过程根本就没有执行PUSH,哪来的将数据压倒栈中呢,楼主本身就没有思考清楚!实验只执行了
0B07:0100 mov ax,2000 
0B07:0103 mov ss,ax 
0B07:0105 mov sp,10 这几部!
zhang898600
[第23楼]   [ 回复时间:2012-07-09 12:02 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2012-06-11 21:15
执行T命令会产生中断,中断程序执行前会将相关寄存器的值入栈保存起来,顺序如下:
先是标志寄存器入栈 
接着CS寄存器入栈 
接着IP寄存器入栈
然后执行中断程序,但是中断程序是一个子程序,这个子程序的开头也会将子程序中用到的一些寄存器的值先入栈保存起来(比如子程序中用到AX,在程序开头就要先PUSH AX,这样做是为了防止原先AX中的内容会被修改),T命令产生的中断例程可能用到了BP,AX寄存器所以会接着将他们入栈,顺序如下: 
接着是BP寄存器入栈 
最着是AX寄存器入栈 
当执行完中断子程序后出栈的顺序如下:
POP AX
POP BP
POP IP
POP CS
POPF(标志寄存器出栈)
此时SP指向的栈顶为空(恢复到了原先状态),但是入栈操作的数据依然会留在内存单元当中,所以T命令的整个过程SP的值是没有发生变化的
asura-king
[第24楼]   [ 回复时间:2012-09-22 21:16 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2012-09-16 00:19
看了上面很多人都说是以进栈的方式写入的。我觉的是不对的,因为在期间sp的内容完全没有改变。
我认为应该是在debug以T调试方式执行下一条指令之前因为发生了“中断”所以会把CS,IP还有AX和一些其他的寄存器中的内容从栈顶以从高到低的方式‘写入’(而不是push)栈中。已达到“保护现场”的目的。
asura-king
[第25楼]   [ 回复时间:2012-09-22 21:16 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2012-09-16 00:19
看了上面很多人都说是以进栈的方式写入的。我觉的是不对的,因为在期间sp的内容完全没有改变。
我认为应该是在debug以T调试方式执行下一条指令之前因为发生了“中断”所以会把CS,IP还有AX和一些其他的寄存器中的内容从栈顶以从高到低的方式‘写入’(而不是push)栈中。已达到“保护现场”的目的。
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved