做一下小測驗,熟悉一下過程幀的結構。
通過下面的代碼,即可找到函數的返回地址:
#include <stdio.h>int evil(int para) { int var = 10; printf("evil\n"); printf("address ¶ is:%p, has value:%p\n", ¶, (void*) *(¶) ); printf("address &var is:%p, has value:%p\n", &var, (void*) *(&var) ); printf("\n"); printf("address &var+1 is:%p, has value:%p\n", &var+1, (void*) *(&var+1) ); printf("address &var+2 is:%p, has value:%p\n", &var+2, (void*) *(&var+2) ); printf("address &var+3 is:%p, has value:%p\n", &var+3, (void*) *(&var+3) ); printf("address &var+4 is:%p, has value:%p\n", &var+4, (void*) *(&var+4) ); printf("address &var+5 is:%p, has value:%p\n", &var+5, (void*) *(&var+5) ); printf("address &var+6 is:%p, has value:%p\n", &var+6, (void*) *(&var+6) ); printf("address &var+7 is:%p, has value:%p\n", &var+7, (void*) *(&var+7) ); printf("address &var+8 is:%p, has value:%p\n", &var+8, (void*) *(&var+8) ); printf("\n"); return var + para;}int main() { int x = 20; printf("\n"); printf("current line is:%d\n",__LINE__); printf("\n"); evil(x);addr: printf("after call evil, the return address is:%p\n",&&addr); printf("\n"); return 0;}
$ gcc main.c
$ ./a.out
current line is:28
evil
address ¶ is:0xbff3f120, has value:0x14
address &var is:0xbff3f10c, has value:0xa
address &var+1 is:0xbff3f110, has value:(nil)
address &var+2 is:0xbff3f114, has value:(nil)
address &var+3 is:0xbff3f118, has value:0xbff3f148
address &var+4 is:0xbff3f11c, has value:0x8048627
address &var+5 is:0xbff3f120, has value:0x14
address &var+6 is:0xbff3f124, has value:0x1c
address &var+7 is:0xbff3f128, has value:0xa5bbdb
address &var+8 is:0xbff3f12c, has value:0xba3324
after call evil, the return address is:0x8048627
從輸出可以看出,
地址&var+4處儲存的值為 0x8048627,與返回地址一樣;
地址&var+5為 0xbff3f120,與evil函數的參數para地址一樣。
所以函數的幀大致是這樣的:
--------------|
...... |
參數 | +5 ¶ 調用者幀
返回地址 | +4
--------------|
...... | +1,2,3
本地變數 | &var 當前幀
--------------|
附:
http://stackoverflow.com/questions/865862/printf-the-current-address-in-c-program