aduna2:
.LFB0:
.cfi_startproc
push ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
mov ebp, esp
.cfi_def_cfa_register 5
sub esp, 16
mov DWORD PTR [ebp-4], 10
mov eax, DWORD PTR [ebp+12]
mov edx, DWORD PTR [ebp+8]
add edx, eax
mov eax, DWORD PTR [ebp+16]
add edx, eax
mov eax, DWORD PTR [ebp-4]
add eax, edx
leave
aduna:
.LFB1:
.cfi_startproc
push ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
mov ebp, esp
.cfi_def_cfa_register 5
sub esp, 28
mov DWORD PTR [ebp-4], 7
mov eax, DWORD PTR [ebp-4]
mov DWORD PTR [esp+8], eax
mov eax, DWORD PTR [ebp+12]
mov DWORD PTR [esp+4], eax
mov eax, DWORD PTR [ebp+8]
mov DWORD PTR [esp], eax
call aduna2
leave
main:
.LFB2:
.cfi_startproc
push ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
mov ebp, esp
.cfi_def_cfa_register 5
and esp, -16
sub esp, 16
mov DWORD PTR [esp+4], 6
mov DWORD PTR [esp], 5
call aduna
mov DWORD PTR [esp+4], eax
mov DWORD PTR [esp], OFFSET FLAT:.LC0
call printf
leave
我在这段代码中有以下问题:在主要内容我无法弄清楚当esp 16相对于ebp时esp的位置。这个问题我在" adunare"和" adunare2"我无法弄明白它与ebp的相对位置。我无法弄清楚是否为这个程序绘制了一个堆栈,因为我所有的堆栈都停留在" adunare2"我得到ebp + 8,ebp + 12,ebp + 16.给我看一个是有帮助的,因为我不明白发生了什么。在每次通话时都会插入一个返回地址?如果是,那么" adunare2"如何使用+ 8,+ 12,+ 16?
获取上述参数这是c代码:
#include<stdio.h>
int aduna2(int a,int b,int c)
{
int d=10;
return a+b+c+d;
}
int aduna(int a,int b)
{
int c=7;
return aduna2(a,b,c);
}
int main()
{
printf("%d\n",aduna(5,6));
}
答案 0 :(得分:0)
即使从不完整的反汇编中,我想我也可以回答“aduna之前堆栈的主要内容”:
main:
; store old ebp value into stack (to restore it before return)
push ebp
mov ebp, esp ; copy current value of esp to ebp
此时esp和ebp都有相同的值,指向堆栈的当前顶部,假设它是0x0054
,那么(堆栈)内存如下所示:
address | value
-----------------
0x0050 | ????
0x0054 | old_ebp <- esp/ebp pointing here
0x0058 | return address to "main" caller
0x005C | whatever was already in stack before calling main
然后代码继续为“aduna”函数准备参数:
and esp, -16 ; -16 = 0xFFFFFFF0 -> makes esp 16B aligned
; esp here is 0x0050
sub esp, 16 ; make room at top of stack for 16B, esp = 0x0040
; store the arguments into the stack
mov DWORD PTR [esp+4], 6 ; at 0x0044 goes value 6
mov DWORD PTR [esp], 5 ; at 0x0040 goes value 5
call aduna ; call aduna
现在进入aduna之后,ebp / esp和堆栈内存如下所示:
ebp = still 0x0054, nothing did modify it
esp = 0x003C (call did pust return address at top of stack)
address | value
-----------------
0x0038 | ????
0x003C | return address to instruction after "call aduna" <- esp
0x0040 | 5
0x0044 | 6
0x0048 | ????
0x004C | ????
0x0050 | ????
0x0054 | old_ebp <- ebp pointing here
0x0058 | return address to "main" caller
0x005C | whatever was already in stack before calling main
aduna
以序言代码push ebp
mov ebp, esp
开头,因此堆栈顶部会有所改变:
address | value
-----------------
0x0038 | 0x0054 <- both esp and ebp pointing here (= 0x0038)
0x003C | return address to instruction after "call aduna"
0x0040 | 5
0x0044 | 6
因此mov eax, DWORD PTR [ebp+12]
将获取地址0x0044(0x38 + 0x0C = 0x44),存储了6. ebp+8
个指向值5.其余esp
/ ebp
组合在aduna
以下的点,进入局部变量(住在记忆的“堆栈”部分),我不打算描述,因为一旦你理解了这个初始部分,你应该能够破译其余部分它也是。
对于leave
,请查看指令集手册(它确实更改了esp
和ebp
)。缺少的ret
也很重要,同时也会更改esp
。