以下是引用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 编辑 ]