我在解释下面这段代码时遇到了问题。我认为8和5应该是数组的成员。但是,如果我定义一个数组,它们存储在ebp-something而不是esp中。我知道如果调用一个函数,变量存储在esp中,但是没有..
main:
pushl %ebp
....
movl $8, 28(%esp)
movl $5, 32(%esp)
movl 28(%esp), %eax
movl %eax, t
movl $0, 36(%esp)
jmp .L1
我得到了什么:
int t;
int main()
{
int array[] = {9, 4, 0, 5, 1, -4, -6, 7};
t = array[0];
return 0;
}
movl $8, -8(%ebp)
movl $5, -4(%ebp)
movl -8(%ebp), %eax
movl %eax, t
非常感谢你的帮助!
答案 0 :(得分:1)
问题不在于使用特定寄存器。 ebp
和esp
都可用于处理堆栈位置;此外,在平面存储器(非分段)32位应用程序中,任何其他寄存器都是可能的(但不是传统的)。主要问题是
sp
进行直接堆栈寻址。 bp
旨在实现此目的。这需要序言(push bp
,mov bp,sp
)和结语。此外,这种风格对于人类来说很方便,因为bp
对于函数调用是固定的,因此偏移量不会发生变化。rsp
,rbp
而不是esp
,ebp
),添加了使用堆栈指针的寻址。这允许编译器避免序言和结尾创建。缺点是每次推送或弹出任何内容时,esp
上的相同堆栈单元的偏移都会改变。编译器处理这个比人类更容易。在你的例子中,你已经错过了主要部分。在思考中,在生成的代码中,esp
在推送ebp
后立即递减了36。这就是为什么-8(%ebp)
与28(%esp)
的地址相同的原因。如果GCC更喜欢ebp
,那么您可以强制在功能中保留框架支持代码,但不能仅使用esp
进行堆栈寻址。