程序調(diào)用過程和堆棧的關(guān)系,為什么要傳地址而不傳值

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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容