|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 matrix04882 于 2015-2-26 14:43 编辑
先看一下我写的代码ASSUME CS:FC0006 ;VIDEO 30
FC0006 SEGMENT
DW 0123H,0456H,0789H,0ABCH,0DEFH,0FEDH,0CBAH,0987H
DW 0,0,0,0,0,0,0,0
ASM001:MOV AX,CS
MOV SS,AX
MOV SP,20H
SUB BX,BX
MOV CX,8
LOP001:PUSH CS:[BX]
ADD BX,2
LOOP LOP001
SUB BX,BX
MOV CX,8
LOP002:POP CS:[BX]
ADD BX,2
LOOP LOP002
MOV AX,4C00H
INT 21H
FC0006 ENDS
END ASM001
再看视频中该程序代码
内容是一样的
那么问题来了,有谁动手编译过该程序.
编译运行后,结果并不会按预期的那样,出现倒序排放那8个字型数据.
再看书中所述内容,
DW设置的是16个空字型数据(即32个字节)作为栈段.
那么问题又来了,明明8个字型数据,为什么要弄一个16个字型数据长度的栈段呢?
难道王爽老师傻的么?当然不是.
这里参考我之前做过的书中实验3中的一次栈段的监视记录就能说明问题:
大家不要关心程序和数值的状态,只要知道上面的是各寄存器的变化值,下面的是我所指定的栈段地址的初始值就好.
来看看运行实验3以后各步骤都在搞什么.
通过观察,推理,一系列的猜疑,和仅有的那么点儿悟性,我发现了一个惊天的秘密(泥垢了!)
大家看看寄存器标的颜色,和这表里的颜色!居然对应上了!
而且!而且!!而且!!!!!!
注意,我用了3个而且!!!
注意我用黑粗框标的这10个字节!
他会随着PUSH和POP来回摆动!一次2个字节!
于是我似乎发现了这么个规律:
无论你在哪设置栈,栈顶之前,至少有10个字节用来存放数据(该数据经过观察,大部分为CPU寄存器相关数据),即上图粗方框内内容。橘色确定为AX内容,绿色确定为IP内容,蓝色为CS内容,其它暂时不知道。该方框内的10个字节数据随着PUSH、POP命令移动。PUSH后,会前移,如果前方有数据会覆盖前方数据。POP后,会后移,因为POP取出两个字节数据,所以后移后,会残留最前方两个数据,即AX的数据,用灰色表示。
这玩意儿会覆盖前方数据(如果有的话),POP后退后,还会残留之前AX的数据!!(所以我推断AX数据是第一个)。
这样,回过头来,王爽老师并不是傻!他给这10个字节的寄存器数据留地方了!!!!
再分析下,如果硬按照甲鱼老师的程序运行会发生神马?
对,当不断的压栈后,把这10个字节的老兄挤到上一排去了!
就是存放数据的那排!我说过,他会覆盖数据!!于是乎,我们悲催的数据就这么不声不响的被干掉了!!
所以,程序并没有按我们希望的结果执行.
再深入的研究了一下,这还是前边有地方可以挤一挤.不算太糟糕.如果前面没地方了呢???
我们来看,下面这两句.
mov ax,2000H
mov ss,ax
mov sp,10H
很简单吧?但是很惨的!
压几下,就把AX压到2000:0000这个地址了,你再压的话,他不会跑到1FFF:0000这行去,相信我,我试过。
因为我分析SS段地址指定了,就像甲鱼老师说的,CPU好像是傻的!他根本不懂得变通。
然后,AX莫名奇妙的就挂了,好吧,可能AX对你来说暂时不重要(喂喂,AX里的值可以随便挂的嘛!?)
但是,你继续压栈的话,就把CS的值给压变形了!!对,变成另外一组数据了(到底是和之前牺牲的AX,IP有没有关系我还没来得及验证呢。)
到这,CS一变,你的程序就不知道被指到哪里去执行那里的命令去了!!对,就这么鬼畜!\("▔□▔)/
所以栈的大小一定要考虑好!而栈前的值直接影响寄存器内的值的变化.
作为新人,码了这么多字的确不容易。感谢看完,非常感谢您的参与。可能后面的视频会讲,可能书中的哪个地方会写,但我目前只学到第6章,这都是我自己发现的,毕竟没有任何编程经验直接学了汇编,高手看完如果有不对的地方请不惜赐教,在此谢过谢过,如果您是和我一样的新人,请不要放过在学习中遇到的任何一个小的细节,深究其原理,刨根问底,透过现象看本质,方为正途。
哦,对了,第三个而且我给涂成白色的了,就像我说的,透过现象看本质。:ton:
希望和我一样学习的新人看到后能起到抛砖引玉的功效,我就知足矣。
|
评分
-
查看全部评分
|