无法理解函数的反汇编
Unable to understand a disassembling of a function
我已将以下简单函数反汇编成此函数但我未能理解一些事情。如果有人能帮助我,我会很高兴
这是我正在反汇编的函数:
int foo(int a, int b, int c){
int t = 4;
int t2 = 5;
int t6 = 6;
t = b;
t2 = c;
return (a *= t6);
}
我使用以下参数从主函数调用它:
foo(2,3,4);
这就是函数被反汇编成的:
.text:004013BE ; _DWORD __cdecl foo(int, int, int)
.text:004013BE public __Z3fooiii
.text:004013BE __Z3fooiii proc near ; CODE XREF: _main+2Dp
.text:004013BE ; _main+5Cp
.text:004013BE
.text:004013BE var_C = dword ptr -0Ch
.text:004013BE var_8 = dword ptr -8
.text:004013BE var_4 = dword ptr -4
.text:004013BE arg_0 = dword ptr 8
.text:004013BE arg_4 = dword ptr 0Ch
.text:004013BE arg_8 = dword ptr 10h
.text:004013BE
.text:004013BE push ebp
.text:004013BF mov ebp, esp
.text:004013C1 sub esp, 10h
.text:004013C4 mov [ebp+var_4], 4
.text:004013CB mov [ebp+var_8], 5
.text:004013D2 mov [ebp+var_C], 6
.text:004013D9 mov eax, [ebp+arg_4]
.text:004013DC mov [ebp+var_4], eax
.text:004013DF mov eax, [ebp+arg_8]
.text:004013E2 mov [ebp+var_8], eax
.text:004013E5 mov eax, [ebp+arg_0]
.text:004013E8 imul eax, [ebp+var_C]
.text:004013EC mov [ebp+arg_0], eax
.text:004013EF mov eax, [ebp+arg_0]
.text:004013F2 leave
.text:004013F3 retn
.text:004013F3 __Z3fooiii endp
- 加载函数的局部变量时
(var_c, var_8, var_4) ESP 指针减去 10h,十进制为 16,我们堆栈内存中的每个变量都是 四个字节 ,并且我有三个局部变量 - 因此 ESP 指针应该减去 12 ( 0Ch ),为什么它会减去 16?
(.text:004013C1 sub esp, 10h)
- 程序的return地址保存在哪一点?还有老的ESP呢?什么时候保存的?
sub esp, 10h
我不太担心这个。虽然这些局部变量只需要 12 个字节,但编译器可能有它的理由总是以 16 个字节为单位进行分配。
In which point the return address of the procedure is saved?
这位于 [ebp+4]
also what about the old ESP?, when is that saved?
leave
指令会将EBP
移动到ESP
,从而恢复堆栈指针。
mov [ebp+arg_0], eax
mov eax, [ebp+arg_0]
我会更担心这些多余的代码。结果已经在 EAX
中。为什么要那样移动它?
我已将以下简单函数反汇编成此函数但我未能理解一些事情。如果有人能帮助我,我会很高兴
这是我正在反汇编的函数:
int foo(int a, int b, int c){
int t = 4;
int t2 = 5;
int t6 = 6;
t = b;
t2 = c;
return (a *= t6);
}
我使用以下参数从主函数调用它:
foo(2,3,4);
这就是函数被反汇编成的:
.text:004013BE ; _DWORD __cdecl foo(int, int, int)
.text:004013BE public __Z3fooiii
.text:004013BE __Z3fooiii proc near ; CODE XREF: _main+2Dp
.text:004013BE ; _main+5Cp
.text:004013BE
.text:004013BE var_C = dword ptr -0Ch
.text:004013BE var_8 = dword ptr -8
.text:004013BE var_4 = dword ptr -4
.text:004013BE arg_0 = dword ptr 8
.text:004013BE arg_4 = dword ptr 0Ch
.text:004013BE arg_8 = dword ptr 10h
.text:004013BE
.text:004013BE push ebp
.text:004013BF mov ebp, esp
.text:004013C1 sub esp, 10h
.text:004013C4 mov [ebp+var_4], 4
.text:004013CB mov [ebp+var_8], 5
.text:004013D2 mov [ebp+var_C], 6
.text:004013D9 mov eax, [ebp+arg_4]
.text:004013DC mov [ebp+var_4], eax
.text:004013DF mov eax, [ebp+arg_8]
.text:004013E2 mov [ebp+var_8], eax
.text:004013E5 mov eax, [ebp+arg_0]
.text:004013E8 imul eax, [ebp+var_C]
.text:004013EC mov [ebp+arg_0], eax
.text:004013EF mov eax, [ebp+arg_0]
.text:004013F2 leave
.text:004013F3 retn
.text:004013F3 __Z3fooiii endp
- 加载函数的局部变量时 (var_c, var_8, var_4) ESP 指针减去 10h,十进制为 16,我们堆栈内存中的每个变量都是 四个字节 ,并且我有三个局部变量 - 因此 ESP 指针应该减去 12 ( 0Ch ),为什么它会减去 16?
(.text:004013C1 sub esp, 10h)
- 程序的return地址保存在哪一点?还有老的ESP呢?什么时候保存的?
sub esp, 10h
我不太担心这个。虽然这些局部变量只需要 12 个字节,但编译器可能有它的理由总是以 16 个字节为单位进行分配。
In which point the return address of the procedure is saved?
这位于 [ebp+4]
also what about the old ESP?, when is that saved?
leave
指令会将EBP
移动到ESP
,从而恢复堆栈指针。
mov [ebp+arg_0], eax
mov eax, [ebp+arg_0]
我会更担心这些多余的代码。结果已经在 EAX
中。为什么要那样移动它?