Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 设置后帧指针指向何处?_Assembly_Stack_X86 - Fatal编程技术网

Assembly 设置后帧指针指向何处?

Assembly 设置后帧指针指向何处?,assembly,stack,x86,Assembly,Stack,X86,尽管我看教科书试图理解这一点,但我还是有困难 0x08048b29 <func+0>: push %ebp 0x08048b2a <func+1>: mov %esp,%ebp 0x08048b2c <func+3>: push %ebx ... 0x08048b30 <phase_2+7>: lea -0x28(%ebp),%eax 0x08048b29:推送%ebp 0x08048b

尽管我看教科书试图理解这一点,但我还是有困难

    0x08048b29 <func+0>: push   %ebp
    0x08048b2a <func+1>: mov    %esp,%ebp
    0x08048b2c <func+3>: push   %ebx
    ...
    0x08048b30 <phase_2+7>: lea    -0x28(%ebp),%eax
0x08048b29:推送%ebp
0x08048b2a:mov%esp,%ebp
0x08048b2c:推送%ebx
...
0x08048b30:lea-0x28(%ebp),%eax

在lea指令中,我了解到%eax在%ebp之前的0x28处获取值,但这到底是在哪里?它是0x8048b29-0x28(函数开始前的0x28)还是什么?

ebp寄存器通常用于函数中访问传递给函数的任何参数。在调用此函数之前,寄存器未传递的任何参数都会推送到堆栈上。此函数开始时,将保存调用函数的基指针

(1)
0x08048b29:推送%ebp

堆栈的新顶部被复制到ebp中,用作此函数中的基指针

(2)
0x08048b2a:mov%esp%ebp

最后,保存ebx,它很可能是传递给寄存器中函数的变量

(3)
0x08048b2c:推送%ebx

在所有这些函数输入代码之后,ebp寄存器指向堆栈的中间。在堆栈的上面(朝向最新推送的项目)是在上面#3中推送的ebx值。在堆栈的下面是调用函数的旧ebp(保存在上面的#1中),最重要的是。。。通过堆栈传递到此函数的任何参数(在调用函数之前完成)

(4)
lea-0x28(%ebp),%eax


最后一条指令引用堆栈传递的其中一个参数。ebp最终指向堆栈,而不是任何函数代码地址。这对于ebp是很正常的,它最常用作堆栈指针。

从调用该函数的上下文来看。执行此操作的代码如下所示:

caller+...: push argN
caller+...: ...
caller+...: push arg0
caller+...: call func
[ebp+4+(N*4)][         ] : argN
...                      : arg(N-1)...arg2
[ ebp+8     ][         ] : arg1
[ ebp+4     ][         ] : <return address to caller()+...>
[ ebp       ][         ] : <saved %ebp of caller>
[ ebp-4     ][         ] : <saved %ebx of caller>
[ ebp-8     ][         ] : ...
...                      : region for local variables
[ ebp-??    ][ esp     ] : end of stack for func()
i、 e.参数按如下顺序放置在堆栈上:在进入
func()
时,堆栈将具有以下布局:

[esp+(N*4)] : argN
...         : arg(N-1)...arg2
[esp+4    ] : arg1
[esp      ] : <return address to caller()+...>
然后,代码继续在堆栈上推送几个寄存器,因为每次
%esp
被-4更改时,寄存器会向下增长。最终(您在反汇编中没有显示,但它会出现)您将有一条指令
subl$…,%esp
。这就是为局部变量分配空间的原因。最终的堆栈布局类似于:

caller+...: push argN
caller+...: ...
caller+...: push arg0
caller+...: call func
[ebp+4+(N*4)][         ] : argN
...                      : arg(N-1)...arg2
[ ebp+8     ][         ] : arg1
[ ebp+4     ][         ] : <return address to caller()+...>
[ ebp       ][         ] : <saved %ebp of caller>
[ ebp-4     ][         ] : <saved %ebx of caller>
[ ebp-8     ][         ] : ...
...                      : region for local variables
[ ebp-??    ][ esp     ] : end of stack for func()
[ebp+4+(N*4)][]:argN
...                      : arg(N-1)…arg2
[ebp+8][]:arg1
[ebp+4][]:
[ebp][]:
[ebp-4][]:
[ebp-8][]:。。。
...                      : 局部变量区域
[ebp-??][esp]:func()的堆栈结束
[esp…ebp-4]
之间的任何地址都在函数的堆栈框架内,它包含代表调用方保存的寄存器(如
ebx
在您显示的反汇编中)或局部变量


因此,当您在代码中看到对
%ebp-XX
的任何访问时,它是在局部变量空间中,如果您看到
%ebp+YY
它是在包含函数参数的空间中。

它们这样做的原因是,参数总是可以被相同的ebp偏移引用。您不能将esp用于此目的,因为此函数可能需要将堆栈指针用于临时push/pop指令。