注册 登录
编程论坛 汇编论坛

关于一个栈空间的问题!

wsm340223 发布于 2012-10-10 16:30, 852 次点击
assume cs:code,ds:data,ss:stack
data segment
dw 0123h,0456h,0789h,0545h,0545h,5454h,54f5h,5456h
data ends
stack segment
dw 0,0,0,0,0,0,0,0,0,0
stack ends
code segment
start: mov ax,stack
       mov ss,ax
       mov sp,0fh
       mov ax,data
       mov ds,ax
      
       mov bx,0
       mov cx,8
s:     push [bx]
       add bx,2
       loop s
      
       mov bx,0
       mov cx,8
s0:     pop [bx]
       add bx,2
       loop s0
      
       mov ax,4c00h
       int 21h
      
code ends
end start


这是个用栈逆序排放数据的程序,红体字的地方,是我设的栈顶位置,数据段有8个字!
今天做这个时,遇到两个问题,
一、用debug单步跟进入栈循环,结果仅两步,debug就停止工作了,想问的是,debug会提前预测到栈空间不足的问题么?
二、栈空间足够的情况下,执行完入栈循环后,查看栈段数据,发现数据并没有从栈底将数据段的数据逆序排放,(例:9,8,7,6,5,4,3,2,1,逆序排放),而是顺序排放,(例:1,2,3,4,5,6,7,8,9)!这是为什么?



[ 本帖最后由 wsm340223 于 2012-10-10 19:15 编辑 ]
13 回复
#2
zklhp2012-10-10 17:47
因为debug和被调试的程序共用一个堆栈 而debug运行的时候也会压栈 所以会出现不够的情况
#3
zklhp2012-10-10 17:48
这个问题主要是因为DOS系统的设计缺陷或者说局限或者说特性、、、
#4
有容就大2012-10-10 17:52
可以把调试步骤发上来看看
其次就是 8个字的话 sp应该指向10h.
#5
wsm3402232012-10-10 18:03
回复 2楼 zklhp
谢谢!第二个问题,您怎么看?
#6
wsm3402232012-10-10 18:07
回复 4楼 有容就大
图片怎么发,蒙了
#7
有容就大2012-10-10 18:14
以下是引用wsm340223在2012-10-10 18:07:55的发言:

图片怎么发,蒙了

很简单就三步
1. 截图 按键盘上的Print Screen键
2. 黏贴 选取 保存 用PS或者 系统自带的画图 或者其他工具
3. 论坛发图
就是下面图片里红框中的按钮
只有本站会员才能查看附件,请 登录

#8
有容就大2012-10-10 18:15
详细的描述自己遇到的问题 利己利人利观众
#9
小习小习2012-10-10 18:23
来学习
#10
小习小习2012-10-10 18:24
以下是引用有容就大在2012-10-10 17:52:43的发言:

可以把调试步骤发上来看看
其次就是 8个字的话 sp应该指向10h.
我也赞成
#11
wsm3402232012-10-10 19:05
回复 8楼 有容就大
哈哈,,,,,,
#12
wsm3402232012-10-10 19:22
回复 4楼 有容就大
谢谢你!
#13
有容就大2012-10-10 20:46
以下是引用wsm340223在2012-10-10 19:22:52的发言:

谢谢你!

不用谢 其实你应该去实验一下 。。。
你会发现一个小小的问题。
在理论上8个字的栈如果是空的话 无疑栈顶指针指向0fh是错误的 而应该指向10h
但是如果改成10h后再去单步调试你的程序(你的栈应该只有8个零) 仍然会在压完第6个字的时候
就会跳出来 什么原因呢?
因为你用8个字空间的栈来装载8个字的ds段数据 这是没有问题的
只要你加载数据段和堆栈段段地址后 用-u命令来查看循环结束的CS:IP 也就是mov ax, 4c00h
的cs:ip 并用-g命令跳转到这里程序是很正常的, 结果可以看到数据段已经全部逆序存放了。
但是如果你用单步调试来执行程序那么就会出现问题 。 在单步调试的时候 -t是一个单步中断
这个中断过程是这样的
取得中断类型码N
pushf  标志寄存器入栈  
TF = 0, IF = 0
push cs 代码段寄存器入栈
push ip 指令指针寄存器入栈
ip = N * 4, cs = N * 4 + 2.

iret 后再pop出原来保护的现场数据。
可以看到在应用程序压栈的同时使用-t来单步调试 要额外要入三个字即6个字节的空间
如果只给这个过程准备了2个字即4个字节的话 只实现了pushf 和 push cs 而 ip这个现场数据没有被保护好,那么到iret后原来的cs 和 ip 就被生生的割断了 程序将跳转到一个未知的地方 保护模式下的cmd就会跳出用户程序返回DOS。

其实这个问题以前我也有很大的疑惑 而感觉初学的人大多有这方面的相似疑问 就写了上面这些东西 希望自己没有理解错。。。




                    


[ 本帖最后由 有容就大 于 2012-10-10 20:52 编辑 ]
#14
chaoc2012-10-24 09:09
回复 13楼 有容就大
这正是我的疑惑之处。多谢解答!
1