我在C中写了一个简单的程序,在GDB中进行分析
#include <stdio.h>
int add_numbers(int n1,int n2)
{
int sum=n1+n2;
return sum;
}
int main()
{
int n1=1;
int n2=2;
int sum;
sum = add_numbers(n1,n2);
printf("The sum of 1 and 2 is %d",sum);
return 0;
}
这是主要
的反汇编0x08048433 <+0>: push %ebp
0x08048434 <+1>: mov %esp,%ebp
0x08048436 <+3>: and $0xfffffff0,%esp
0x08048439 <+6>: sub $0x20,%esp
0x0804843c <+9>: movl $0x1,0x14(%esp)
0x08048444 <+17>: movl $0x2,0x18(%esp)
0x0804844c <+25>: mov 0x18(%esp),%eax
0x08048450 <+29>: mov %eax,0x4(%esp)
0x08048454 <+33>: mov 0x14(%esp),%eax
0x08048458 <+37>: mov %eax,(%esp)
0x0804845b <+40>: call 0x804841d <add_numbers>
0x08048460 <+45>: mov %eax,0x1c(%esp)
0x08048464 <+49>: mov 0x1c(%esp),%eax
0x08048468 <+53>: mov %eax,0x4(%esp)
0x0804846c <+57>: movl $0x8048510,(%esp)
0x08048473 <+64>: call 0x80482f0 <printf@plt>
0x08048478 <+69>: mov $0x0,%eax
0x0804847d <+74>: leave
0x0804847e <+75>: ret
然后我在第12行设置断点并分析堆栈 &#39; x / 20x $ esp&#39;
0xbffff270: 0x00000001 0xbffff334 0xbffff33c 0xb7e4342d
0xbffff280: 0xb7fbb3c4 0x00000001 0x0804848b 0xb7fbb000
0xbffff290: 0x08048480 0x00000000 0x00000000 0xb7e29a83
0xbffff2a0: 0x00000001 0xbffff334 0xbffff33c 0xb7feccea
0xbffff2b0: 0x00000001 0xbffff334 0xbffff2d4 0x0804a014
那么为什么声明&#39; movl $ 0x1,0x14(%esp)&#39;将1移动到堆栈中的第二个地址?具体来说,这个堆栈是如何递增(或递减,因为堆栈增长?)来放置&#39; 1&#39;在&#39; $ eip&#39;之后的地址中注册
教程也很好,因为我可能错过了这些信息。 谢谢!
- 汤姆
答案 0 :(得分:2)
汇编指令movl $0x1,0x14(%esp)
将32位整数值1
移动到位于寄存器ESP指向的地址之后20个字节的4个字节中。在你的内存转储中,这是从0xbffff284
开始的四个字节,这是第二行的第二个32位值。
此指令不会更改ESP的值。它既不增加也不减少。 ESP中的值先前由0x08048439
:sub $0x20,%esp
处的指示更改。该指令在堆栈上为函数使用的局部变量保留32个字节,以及函数调用的传出参数。变量n1
,n2
和sum
分别位于地址0xbffff284
,0xbffff288
和0xbffff28c
。
在程序中的任何位置,EIP后面的地址都没有存储。我认为你实际上意味着其他的东西,但我不知道是什么。