与C++和Assembly相关,什么是ebp + 8?

j.D*_*Doe 8 c++ x86 assembly g++ reverse-engineering

我有以下C++代码:

#include <tuple>
std::tuple<int, bool> foo()
{
    return std::make_tuple(128, true);
}
int main()
{
    auto result = foo();
}
Run Code Online (Sandbox Code Playgroud)

以下是该foo()函数的反汇编版本:

push    ebp
mov     ebp, esp
sub     esp, 24
mov     BYTE PTR [ebp-13], 1  // second argument
mov     DWORD PTR [ebp-12], 128 // first argument
mov     eax, DWORD PTR [ebp+8] // what is this? why we need this here?
sub     esp, 4
lea     edx, [ebp-13]   
push    edx                   // second
lea     edx, [ebp-12]
push    edx                   // first
push    eax                  // same as "ebp+8", what is this?
call    std::tuple<std::__decay_and_strip<int>::__type, std::__decay_and_strip<bool>::__type> std::make_tuple<int, bool>(int&&, bool&&)
add     esp, 12
mov     eax, DWORD PTR [ebp+8]
leave
ret     4
Run Code Online (Sandbox Code Playgroud)

我所知道的ebp+X是访问函数参数,但没有这样的东西foo,为什么编译器会使用它呢?这似乎是第一个参数std::make_tuple().

编辑:

我没有使用优化,我只想学习RE.

大会的主要部分:

lea     eax, [ebp-16]  // loaction of local variable
sub     esp, 12
push    eax           // as hidden argument for foo
call    foo()
add     esp, 12
Run Code Online (Sandbox Code Playgroud)

Jes*_*ter 12

调用约定指定通过作为参数传递的隐藏指针返回非平凡对象.这就是你所看到的.从技术上讲,您的代码实现如下:

std::tuple<int, bool>* foo(std::tuple<int, bool>* result)
{
    *result = std::make_tuple(128, true);
    return result;
}
int main()
{
    std::tuple<int, bool> result;
    foo(&result);
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,但是你必须检查`eax`是如何设置的,你可能会看到类似`lea eax,[ebp-x]`的东西,它应该指向你这样一个事实:它是一个局部变量的地址. main`,当然只能是`结果'本身. (2认同)