| 我们调用这个函数:
   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] 下一页 |