好吧,堆栈是如何工作的?例如说明:
push ax
等于:
sub sp, 4
mov sp, ax
其中sp是堆栈指针。是吗?
我的问题是 - 如果片刻后我将其更改为整个不同的值,那么从sp寄存器中减去4是什么意思?
答案 0 :(得分:5)
我认为应该阅读
mov [sp], ax
也就是说,将ax的值放入sp。
指向的内存中答案 1 :(得分:0)
您正在将ax
的值移动到下一个可用的堆栈帧中。堆栈指针是向下构建的(因此,如果你有太多的值,它下溢超过零并引发错误而不是溢出到重要的东西),所以下一个可用的堆栈帧位置是当前位置之前的一个字(4个字节)。
答案 2 :(得分:0)
这不是push ax
的工作方式。你的“等于”的代码示例应该是:
sub sp, 4
mov [ss:sp], ax
您不会使用AX覆盖SP的值。您可以将AX复制到SS:SP指向的内存地址(使用堆栈段,而不是数据段)......但实际上,这甚至不准确。你真正需要的是这样的:
mov [tmp], sp
pushf ;push flags
sub [tmp], 4
popf
mov sp, [tmp]
mov [ss:sp], ax
但实际上,即使这不是完全准确的。 mov sp, [tmp]
会导致隐式cli
也被执行(期待mov ss, foobar
),这可能是不可取的
基本上,push
做了很简单的事情,但围绕这个简单事情的细节使它非常值得制作它自己的指令。
答案 3 :(得分:0)
不同之处在于sub esp, 4
将设置标志,但push不会设置标志。此外,它应该是mov [esp],eax
。您显示的16位版本表明您使用的是旧书。没有人在16位机器上编程(可能除了嵌入式微控制器)。
在x86上,OF,SF,ZF,ZF,PF和CF标志将通过减法设置,但PUSH
不会影响任何标志。