弹出操作后数据是不是保留在堆栈中?
Posted
技术标签:
【中文标题】弹出操作后数据是不是保留在堆栈中?【英文标题】:Does data remain in stack after pop operation?弹出操作后数据是否保留在堆栈中? 【发布时间】:2021-08-14 04:56:52 【问题描述】:我知道pop
指令是这样做的:
从栈顶加载值到指定位置 使用目标操作数(或显式操作码),然后递增 堆栈指针
但是当我pop
它时我无法访问数据!
我有这个代码:
mov ah , 0x0e
mov bp, 0x8000
mov sp , bp
push 'A'
mov al , [0x7ffe]
int 0x10 ; print A
pop bx
mov al ,bl
int 0x10 ; print A
mov al , [0x7ffe]
int 0x10 ; **print random chare !**
jmp $
times 510-($-$$) db 0
dw 0xaa55
为什么第三个int 0x10
不打印'A'?
【问题讨论】:
因为int 0x10
本身使用堆栈并且通过弹出您释放了所有权因此它被覆盖。
与标题问题相关:Is it valid to write below ESP?(在存储之后移动(E)SP基本上相当于首先存储在(E)SP下方)。当然,现代操作系统下的用户空间意味着您的堆栈不会被用于异步中断处理程序。例如在 Linux 下,int 0x80
系统调用不会影响用户空间进程的堆栈。
@PeterCordes 在 UNIX 下运行时,堆栈仍将用于信号处理程序帧等。
对,这就是我对那个链接问题的回答所说的。 :P 我可能不应该提到异步硬件中断,因为我真正想说的一点是使用 int
或 syscall
指令不会造成同步破坏。
【参考方案1】:
在第一个 mov al, [0x7ffe]
处,您可以访问地址 0x7FFE 处的内存,因为您只是使用 push
为您的堆栈保留了它,但是在您使用 pop
之后,堆栈指针增加并释放了该地址。您不再拥有它的所有权,因此其他进程可以使用该地址并覆盖您的存储值。这就是为什么您会在该地址获得一个明显随机的数字。
【讨论】:
如果您在pop
之后立即阅读[0x7ffe]
,而不是像int
那样运行使用堆栈的指令,那么可能您仍然会看到您的价值。 (由于这是 16 位实模式,因此没有单独的内核堆栈用于中断上下文)。如果您确实删除了 int,那么只有在推送和加载之间出现外部中断(或者调试器在单步执行时使用了该空间)时,它才会被搞砸。 DOS 不是多任务操作系统,因此它不是像 Unix 那样的操作系统进程意义上的“其他进程”。也许说“其他事情”更好。以上是关于弹出操作后数据是不是保留在堆栈中?的主要内容,如果未能解决你的问题,请参考以下文章