我目前正在学习堆栈(x86)。我知道这是一堆按照后进先出原则操作的数据。我知道关于堆栈的基本操作是push (在堆栈顶部添加值)和pop (删除值)。ESP是对我们现在在堆栈上的位置的引用。现在,我不明白的是:
示例:
Push 4
Push ebx
Push eax上面的指令将生成一个堆栈,如下所示:
8 eax <-- ESP
4 ebx
0 4其中ESP指向最后一个附加值eax。
现在,当我们用pop操作展开这些指令时,我们将得到如下内容:
Push 4
Push ebx
Pop ebx
Push eax上面的指令应该(如果我是正确的)得到下面的堆栈(对于前三个指令):
4 (ebx)
0 4 <-- ESPEbx从堆栈中移除,并且ESP已经向下移动了4位。现在执行完所有指令后的堆栈:
4 eax <-- ESP
0 4我希望到这里为止的一切都是正确的,如果没有的话,欢迎评论;-)现在来看指令mov edx,ebx,+04,从这篇文章的第一个堆栈开始。结果如下所示:
16 eax
8 edx <-- ESP
4 ebx
0 4它将从ebx +4位开始写入edx,将先前的值( eax )移到顶部,还是将eax替换为edx?
第二个问题是(更一般地)如何初始化、寻址和删除堆栈上的数组。
对于这个冗长的问题,我很抱歉,但我想了解一下堆栈的基础知识。谢谢。
发布于 2010-12-10 01:51:56
我希望到这里为止的一切都是正确的,如果不是,欢迎评论;-)现在开始说明mov edx,ebx,+04,从这篇文章的第一个堆栈开始。结果如下所示:
16 eax 8 edx <-- ESP 4 ebx 0 4
它将从ebx +4位开始写入edx,将先前的值( eax )移到顶部,还是将eax替换为edx?
mov edx, [ebx + 4]会将[ebx + 4]处的值移动到edx中(这是一个指针引用,除非ebx指向堆栈(高级:它可能指向堆栈,但引用它不会以任何方式更改堆栈),否则它与当前堆栈没有任何关系。这似乎在多个方面与你的理解不同。
首先,请记住,mov指令的参数用作mov DEST, SRC,而不是相反。
其次,此mov操作仅将[ebx + 4]处的值移动到edx中,因此不会以任何方式更改堆栈指针(此处为ESP)。堆栈将与您在此处引用的第一个堆栈保持不变。为清楚起见,堆栈将保持为:
8 eax <-- ESP
4 ebx
0 4堆栈上的任何值都不会以任何方式更改。
另外,我假设您使用的是32位架构。在这种情况下,像eax之类的寄存器将是32位(4字节)。请记住,这些是4个字节,而不是位。
你的“第二个问题”在这里属于独立的问题,有更多的信息。祝好运!
发布于 2010-12-10 01:59:21
mov edx, [ebx+04]从地址es:ebx+04获取数据并将其放入edx。也许你指的是mov [ebx+04], edx?在这种情况下,它将覆盖地址es:ebx+4.处的所有内容假设es指向堆栈段,并且ebx等于esp,则堆栈将如下所示:
12 edx <-- [ebx+4]
8 edx <-- esp = ebx
4 ebx
0 4发布于 2010-12-10 02:08:55
这个问题是非常错误的。
push ebx将来自ebx寄存器的值放入堆栈,而不是寄存器本身。通过将ebx寄存器的值放入堆栈,您不能将其用作寻址的基数。此外,没有指令(或方法)可以在内存中间“插入”某些内容。它是一个数组,而不是动态列表。
正如我在评论中所说的,我认为您不了解汇编的基础知识。阅读内存模型,寄存器,基本指令,编写一些程序。
https://stackoverflow.com/questions/4401183
复制相似问题