我们调用这个函数:
0x8048451 : call 0x8048440
如我们已经通过CALL调用解释的那样,我们PUSH指令addl $0xc,%esp的地址0x8048456到堆栈。函数RET调用后,我们加12或者十六进制中的0xc(因为我们推入3个参数到堆栈中,每一个分配了4个字节(整型))。
接着我们离开main()函数,并且返回:
0x8048459 <main+17>: leave
0x804845a <main+18>: ret
|
好,在函数f()内部发生了什么呢?
(gdb)
disas f
Dump of assembler code for function f:
0x8048440 <f>: pushl %ebp
0x8048441 <f+1>: movl %esp,%ebp
0x8048443 <f+3>: subl $0x4,%esp
0x8048446 <f+6>: leave
0x8048447 <f+7>: ret
End of assembler dump.
(gdb)
|
开始两个指令都是一样的。它们是程序引入。接着我们看a:
0x8048443 : subl $0x4,%esp
从ESP减去了4个字节。这是为局部变量z分配空间。记得我们定义它为char z[4]?它是一个4字节的字符数组。最后,在末尾,函数返回:
0x8048446 <f+6>: leave
0x8048447 <f+7>: ret
|
好,让我们看另外一个例子:
b.c :
void f(int a, int b, int c)
{
char foo1[6];
char foo2[9];
}
void main()
{
f(1,2,3);
}
|
编译并且启动gdb,解析f:
[murat@victim murat]$ gcc -g b.c -o b
[murat@victim murat]$ gdb -q ./b
(gdb) disas f
Dump of assembler code for function f:
0x8048440 <f>: pushl %ebp
0x8048441 <f+1>: movl %esp,%ebp
0x8048443 <f+3>: subl $0x14,%esp
0x8048446 <f+6>: leave
0x8048447 <f+7>: ret
End of assembler dump.
(gdb)
|
可以看出,从ESP中减去了0x14(20字节),尽管foo1和foo2的总长度只有9+6=15。这样的原因是,内存,还有堆栈,在4字节框架下编址。这意味着,你不能简单的PUSH 1字节数据到堆栈中。或者4字节或者为空。
共3页: 上一页 [1] 2 [3] 下一页
|