电壶胆 发表于 2011-12-28 23:05:59

关于 检测点6.1第二题 内容详解

本帖最后由 电壶胆 于 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
    pop cs:    ;此条指令为所填第三空
    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
       ----- (这是第三空) 分析:这里有2中答案,都可以实现程序目的:
第一种,到这个时候,我们已经清楚前面程序已经将内存单元的数据依次压入栈空间了,而且压入栈空间的数据我们可以准确的定位,就是 cs:,这里不懂的详细看教材,既然可以准备定位刚入栈的数据,自然可以准确的覆盖程序中的数据:既 mov cs:,cs: ,这是本题最容易理解的一种答案,而且内存中的数据依次还保持在栈中。看到这里,我们知道程序定义的10个字空间,我们只利用了8个字空间,还有2个没利用起来,所以即使减少2个字空间,也不会出现数据溢出问题,也就是说初始化sp的时候可以sp-4都可以,自然sp-1,sp-2,sp-3也是安全的,既用这个命令时 第一空的答案是24H最为安全,但是20H,21H,22H,23H也不会出错!
第二种:利用 pop 命令,将刚入栈的数据马上弹出去,依次保持在cs:中,完整命令就是 psp cs: 因为数据始终只占用了一个字的空间,所以在初始化sp的时候, 12H=<sp<=24H都不会出错;
       add bx,2
       loop s
       int 21h
codesg ends
end start

分析完毕

laiyihan 发表于 2011-12-29 00:58:16

终于明白第二空为什么有的参考答案是1a了 还以为自己的24H是错了呢
太感谢了
页: [1]
查看完整版本: 关于 检测点6.1第二题 内容详解