Assembly pop操作后数据是否保留在堆栈中?

Assembly pop操作后数据是否保留在堆栈中?,assembly,x86,stack,Assembly,X86,Stack,我知道pop指令执行以下操作: 将值从堆栈顶部加载到指定的位置 使用目标操作数(或显式操作码),然后递增 堆栈指针 但是当我popit时,我无法访问数据 我有以下代码: 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 ;

我知道
pop
指令执行以下操作:

将值从堆栈顶部加载到指定的位置 使用目标操作数(或显式操作码),然后递增 堆栈指针

但是当我
pop
it时,我无法访问数据

我有以下代码:

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'?

在第一个
mov al,[0x7ffe]
您可以访问地址0x7ffe处的内存,因为您只是用
push
为堆栈保留了它,但在使用
pop
之后,堆栈指针增加并释放了该地址。您不再拥有该地址的所有权,因此其他进程可以使用该地址,并将覆盖您的存储值。这就是为什么你在那个地址会得到一个明显的随机数。

因为
int0x10
本身使用堆栈,通过弹出你释放了所有权,所以它会被覆盖。与标题问题相关:(在存储之后移动(E)SP基本上等同于首先存储在(E)SP之下)。当然,现代操作系统下的用户空间意味着堆栈不会用于异步中断处理程序。e、 g.在Linux下,
int 0x80
系统调用不会影响用户空间进程的堆栈。@PeterCordes在UNIX下运行时,堆栈仍将用于信号处理程序帧等。对,这就是我对该链接问题的回答:P我可能不应该提到异步硬件中断,因为我真正想说的一点是,使用
int
syscall
指令不会产生同步碰撞。如果在
pop
之后立即阅读
[0x7ffe]
,而不是像
int
那样运行使用堆栈的指令,那么你很可能仍然会看到自己的价值。(因为这是16位实模式,所以中断上下文没有单独的内核堆栈)。如果您确实删除了int,那么只有在推送和加载之间出现外部中断(或者调试器在单步执行时使用了该空间)时才会将其弄糟。DOS不是一个多任务操作系统,因此它不是Unix操作系统进程意义上的“其他进程”。也许最好说“其他事情”。