|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 电壶胆 于 2011-12-29 22:21 编辑
assume cs:codesg
codesg segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
dw 0,0,0,0,0,0,0,0,0,0
start:
mov ax,cs ;cs为所填第一空
mov ss,ax
mov sp,24h ;此条指令为所填第二空
mov ax,0
mov ds,ax
mov bx,0
mov cx,8
s:
push [bx]
pop cs:[bx] ;此条指令为所填第三空
add bx,2
loop s
mov ax,4c00h
int 21h
codesg ends
end start
分析:assume cs:codesg
codesg segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
dw 0,0,0,0,0,0,0,0,0,0 ;分析,程序一共开拓了10+8 共18个字(36个字节)的连续数据空间,段地址保持在cs中,偏移地址从0~35(既十六进制的23h,注意偏移地址为0时也算一个字节空间)
start:mov ax,--(这儿是第一空) :分析,这里很好理解,初始化栈空间数据,栈空间就利用程序开始开辟的数据空间,数据段地址默认保持在cs中,自然栈空间的段地址直接从cs中获得即可,既 mov ax,cs
mov ss,ax
mov sp,-- (这是第二空) :分析,从这里开始,其实可以有多个答案,都能达到程序的目的,请听我详细分析最容易理解的一种:题目要求程序开始定义的8个字后面又联系开辟了10个字空间做为栈空间,所以栈的段地址为cs(第一空已阐述),但栈的偏移地址sp地址应该是多少?首先必须明确,栈空间为cs:15~cs:35(注意,这里是10进制,是35,不是36因为0也代表一个字节),但是初始化栈空间的时候,栈内是空的,这时,sp指向最后一个字空间(cs:34)的下一个字空间,既:sp=sp+2,34+2=36,这时sp的值为36,换成16进制为24H,之所有有朋友理解成25H,是因为忽略了当sp=0时其实也表示了一个字节空间,从0开始计算到35就已经有18个字空间了了,所以多计算了一位;
mov ax,0
mov ds,ax
mov bx,0
mov cx,8
s:push [bx]
----- (这是第三空) 分析:这里有2中答案,都可以实现程序目的:
第一种,到这个时候,我们已经清楚前面程序已经将内存单元的数据依次压入栈空间了,而且压入栈空间的数据我们可以准确的定位,就是 cs:[sp],这里不懂的详细看教材,既然可以准备定位刚入栈的数据,自然可以准确的覆盖程序中的数据:既 mov cs:[bx],cs:[sp] ,这是本题最容易理解的一种答案,而且内存中的数据依次还保持在栈中。看到这里,我们知道程序定义的10个字空间,我们只利用了8个字空间,还有2个没利用起来,所以即使减少2个字空间,也不会出现数据溢出问题,也就是说初始化sp的时候可以sp-4都可以,自然sp-1,sp-2,sp-3也是安全的,既用这个命令时 第一空的答案是24H最为安全,但是20H,21H,22H,23H也不会出错!
第二种:利用 pop 命令,将刚入栈的数据马上弹出去,依次保持在cs:[bx]中,完整命令就是 psp cs:[bx] 因为数据始终只占用了一个字的空间,所以在初始化sp的时候, 12H=<sp<=24H都不会出错;
add bx,2
loop s
int 21h
codesg ends
end start
分析完毕 |
|