2017-01-03 67 views
8

Mam następujący C++ kod:Związany z C++ i Assembly, co to jest ebp + 8?

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

Poniżej znajduje się rozmontować wersja funkcji 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 

co wiem ebp+X jest dla argumentów funkcji dostępu, ale nie ma nic takiego dla foo, dlaczego więc kompilator go używa? Wygląda na to, że jest to pierwszy parametr dla std::make_tuple().

EDIT:

nie używam optymalizacji, po prostu chcę, aby dowiedzieć się re.

Część główną w Zgromadzeniu:

lea  eax, [ebp-16] // loaction of local variable 
sub  esp, 12 
push eax   // as hidden argument for foo 
call foo() 
add  esp, 12 
+0

Jaki poziom optymalizacji, wersja kompilatora, opcje kompilatora i inne ustawienia? –

+0

@NickC bez żadnej optymalizacji. gcc -m32 c.cpp –

+1

https://www.cs.uaf.edu/2005/fall/cs301/support/x86/index.html –

Odpowiedz

12

Konwencja określa, że ​​powołanie niebanalną obiekty są zwracane przez ukryty wskaźnik przekazany jako argument. To właśnie widzisz. Technicznie Twój kod jest zaimplementowany w następujący sposób:

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); 
} 
+0

Miałem takie myśli :)) dzięki: d –

+0

Jeśli spojrzysz na sposób, w jaki się go wywołało, mogło to również pomóc;) Zapoznaj się także z odpowiednią dokumentacją konwencji telefonicznej. – Jester

+0

push eax; call foo(); –