1. 程式人生 > >函式調用匯編程式碼分析

函式調用匯編程式碼分析

c語言程式碼和彙編後的彙編程式碼分別如下圖所示:

在main函式中返回值f(2)+1,所以首先呼叫f(2)函式,在呼叫f(2)函式之前要先儲存main函式目前的狀態,棧基址指標,棧指標 之間的內容是main函式執行存放在棧中的內容,保護這兩個暫存器之間的內容可以保證返回main函式後可以使棧中的內容不被破壞。

pushl %ebp  ,movl %esp,%ebp    ,subl $4,%esp   

以上兩條指令將ebp壓棧,將esp作為新的ebp,通過subl $4,%esp 將esp地址下移以為,在ebp之上重新構造一個新函式的棧空間,esp指向新的棧頂。

movl  $2,(%esp)    ,  call   f      

  將f函式的引數2放入esp所指向的地址空間,傳入f函式中,跳轉到f中。

  f:

pushl %ebp    movl  %esp ,%ebp     subl $4,%esp  movl 8(%ebp),%eax movl %eax,(%esp)   call g 

進入f函式後,由於要呼叫g函式,所以和在main函式中呼叫f函式相同,將ebp壓棧,esp作為新的棧低,重新構造一個堆疊,先將main函式中呼叫f函式傳送的引數取出送往eax中,然後將要傳入g函式的引數傳入(%esp) 中,然後跳轉到新的函式g中。

g:

pushl %ebp  movl %esp,%ebp   movl 8(%ebp),%eax  addl $2,%eax   popl %ebp ret

如前函式構造一個新的堆疊,將呼叫g函式傳送的引數取出送往eax中,完成函式呼叫後,還是將傳回的引數放在eax中,退出的在g函式所建立的堆疊,將之前壓入棧中的上一個堆疊的ebp彈出,恢復上一個堆疊,返回到上一層函式。

f:

leave  ret 

在f函式中無函式執行,傳回的引數仍然在eax中,保持不動,恢復上一級main函式的堆疊,返回上一級函式main()。

main:

 addl    $1,%eax   leave   ret

沿著被呼叫後的函式後執行,返回的引數仍然存放在eax中,執行完main函式中程式碼後,將所建立的堆疊退回之前的狀態。