我有以下程序:哪裏的參數是在gdb和ret的?
void test_function(int a,int b, int c, int d){
int flag;
char buffer[10];
flag = 31337;
buffer[0]='A';
}
int main(){
test_function(1,2,3,4);
}
我gcc -g
選項編譯它。
我設置了2個斷點之一,在main和main之後的test_function調用之前。
(gdb) list
1 void test_function(int a,int b, int c, int d){
2 int flag;
3 char buffer[10];
4
5 flag = 31337;
6 buffer[0]='A';
7 }
8
9 int main(){
10 test_function(1,2,3,4);
(gdb) break 10
Breakpoint 1 at 0x804843c: file stackexample.c, line 10.
(gdb) break test_function
Breakpoint 2 at 0x804840a: file stackexample.c, line 1.
(gdb) run
Starting program: /root/tests/c-tests/./stackexample
Breakpoint 1, main() at stackexample.c:10
10 test_function(1,2,3,4);
(gdb) i r esp ebp eip
esp 0xbffff4d0 0xbffff4d0
ebp 0xbffff4e8 0xbffff4e8
eip 0x804843c 0x804843c <main+9>
據我所知,0xbffff4d0
該地址是堆棧(頂部最高地址)的當前底部,這將被用於新的堆棧幀的test_function的號召之後的創建(參考)。
(gdb) x/5i $eip
=> 0x804843c <main+9>: mov DWORD PTR [esp+0xc],0x4
0x8048444 <main+17>: mov DWORD PTR [esp+0x8],0x3
0x804844c <main+25>: mov DWORD PTR [esp+0x4],0x2
0x8048454 <main+33>: mov DWORD PTR [esp],0x1
0x804845b <main+40>: call 0x8048404 <test_function>
在test_function調用之前,參數與這些mov
指令一起存儲。
(gdb) info frame
Stack level 0, frame at 0xbffff4f0:
eip = 0x804843c in main (stackexample.c:10); saved eip 0xb7e8bbd6
source language c.
Arglist at 0xbffff4e8, args:
Locals at 0xbffff4e8, Previous frame's sp is 0xbffff4f0
Saved registers:
ebp at 0xbffff4e8, eip at 0xbffff4ec
(gdb) cont
Continuing.
Breakpoint 2, test_function (a=1, b=2, c=3, d=4) at stackexample.c:1
1 void test_function(int a,int b, int c, int d){
(gdb) info frame
Stack level 0, frame at 0xbffff4d0:
eip = 0x804840a in test_function (stackexample.c:1); saved eip 0x8048460
called by frame at 0xbffff4f0
source language c.
Arglist at 0xbffff4c8, args: a=1, b=2, c=3, d=4
Locals at 0xbffff4c8, Previous frame's sp is 0xbffff4d0
Saved registers:
ebp at 0xbffff4c8, eip at 0xbffff4cc
(gdb) i r esp ebp eip
esp 0xbffff4a0 0xbffff4a0
ebp 0xbffff4c8 0xbffff4c8
eip 0x804840a 0x804840a <test_function+6>
因此,這裏顯而易見的是,第一幀的esp成爲該幀的當前起始地址。雖然我沒有得到的是在哪個堆棧幀的參數?因爲...
(gdb) info locals
flag = 134513420
buffer = "\377\267\364\237\004\b\350\364\377\277"
這裏我們看不到args。如果我們..
(gdb) info args
a = 1
b = 2
c = 3
d = 4
(gdb) print &a
$4 = (int *) 0xbffff4d0
(gdb) print &b
$5 = (int *) 0xbffff4d4
(gdb) print &c
$6 = (int *) 0xbffff4d8
(gdb) print &d
$7 = (int *) 0xbffff4dc
所以在這裏我們看到,參數從第一個地址,這個當前棧幀有這0xbffff4d0
而另一個問題是,下面根據該輸出開始
(gdb) x/16xw $esp
0xbffff4a0: 0xb7fc9ff4 0x08049ff4 0xbffff4b8 0x0804830c
0xbffff4b0: 0xb7ff1080 0x08049ff4 0xbffff4e8 0x08048499
0xbffff4c0: 0xb7fca324 0xb7fc9ff4 0xbffff4e8 0x08048460
0xbffff4d0: 0x00000001 0x00000002 0x00000003 0x00000004
地址0x08048460
是eip = 0x804840a in test_function (stackexample.c:1); saved eip 0x8048460
並且還`#1 0x08048460在main()在stackexample.c:10(從回溯輸出)
如何來和主要是在頂部(到一個較低的地址)比爭論?不應該ret地址在新的堆棧幀的開始?對不起,但我想了解堆棧如何工作,我有點困惑:S另一件我不明白的地方是本地變量的引用是通過$ esp +(offset)發生的。 esp的值是否總是取決於執行的「當前」堆棧幀?
與論壇網站不同,我們不使用「謝謝」或「任何幫助表示讚賞」,或在[so]上簽名。請參閱[應該'嗨','謝謝',標語和致敬辭職](http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be-刪除 - 從 - 個)。 – rene