bug.c
void swap(int a, int b)
{
int c;
c = a;
a = b;
b = c;
}
int main()
{
int a,b;
a = 16;
b = 32;
swap(a, b);
return (a-b);
}
使用gdb調(diào)試,main函數(shù)反匯編的代碼
(gdb) x /20i $pc
=> 0x40135c <main+14>: movl $0x10,0x1c(%esp)
0x401364 <main+22>: movl $0x20,0x18(%esp)
0x40136c <main+30>: mov 0x18(%esp),%eax
0x401370 <main+34>: mov %eax,0x4(%esp)
0x401374 <main+38>: mov 0x1c(%esp),%eax
0x401378 <main+42>: mov %eax,(%esp)
0x40137b <main+45>: call 0x401334 <swap>
0x401380 <main+50>: mov 0x18(%esp),%eax
0x401384 <main+54>: mov 0x1c(%esp),%edx
0x401388 <main+58>: mov %edx,%ecx
0x40138a <main+60>: sub %eax,%ecx
0x40138c <main+62>: mov %ecx,%eax
0x40138e <main+64>: leave
0x40138f <main+65>: ret
swap函數(shù)的反匯編代碼
(gdb) x /20i 0x401334
0x401334 <swap>: push %ebp
0x401335 <swap+1>: mov %esp,%ebp
0x401337 <swap+3>: sub $0x10,%esp
0x40133a <swap+6>: mov 0x8(%ebp),%eax
0x40133d <swap+9>: mov %eax,-0x4(%ebp)
0x401340 <swap+12>: mov 0xc(%ebp),%eax
0x401343 <swap+15>: mov %eax,0x8(%ebp)
0x401346 <swap+18>: mov -0x4(%ebp),%eax
0x401349 <swap+21>: mov %eax,0xc(%ebp)
0x40134c <swap+24>: leave
0x40134d <swap+25>: ret
在執(zhí)行到call swap函數(shù)之前,main函數(shù)的esp和ebp的值,以及棧中內(nèi)容的情況
main函數(shù)的sp和ebp
(gdb) info r esp
esp 0x28ff00 0x28ff00
(gdb) info r ebp
ebp 0x28ff28 0x28ff28
main函數(shù)棧中的內(nèi)容,esp是棧頂
0x28ff00: 0x10 0x00 0x00 0x00 0x20 0x00 0x00 0x00
從這里看,esp存放的是a的值,esp+4存放的是b的值,swap函數(shù)進行操作的也是這塊內(nèi)存.
?那么a,b真正的地址在哪?
main函數(shù)里面
(gdb) p /x &a
$1 = 0x28ff1c
(gdb) p /x &b
$2 = 0x28ff18
swap函數(shù)里面
(gdb) p /x &a
$2 = 0x28ff00
(gdb) p /x &b
$3 = 0x28ff04
可見swap函數(shù)操作的main函數(shù)的a,b在棧上的備份,執(zhí)行完swap函數(shù)返回后,這部分棧就被廢棄了,而a,b真正所在地的值并沒有得到更改.
而swap函數(shù)的堆棧在哪?
從0x28fee8到0x28ff00(一個保存的ebp,三個形參,總計16字節(jié)),函數(shù)的返回地址是屬于main函數(shù)的堆棧,從0x28ff00-04,這是swap的返回地址剛好是call swap的下一條指令
(gdb) x /32bx 0x28fee8
0x28fee8: 0x08 0xff 0x28 0x00 0xc4 0xff 0x28 0x00
0x28fef0: 0xd5 0x8c 0x47 0x77 0xd2 0x10 0x70 0x9a
0x28fef8: 0x28 0xff 0x28 0x00 0x80 0x13 0x40 0x00
0x28ff00: 0x10 0x00 0x00 0x00 0x20 0x00 0x00 0x00
swap函數(shù)的返回地址
0x401380 <main+50>: mov 0x18(%esp),%eax