程序的機器級表示(三)——C語言的相關語句


不說那麼多鬼言鬼語,開始今天的內容。

過程(函數)調用

過程蘊含了抽象的思想,提供了代碼封裝的方式(information hiding和interface的內容,c++系列筆記中會有)
過程不僅僅包括函數,但是我們這裏以調用函數理解過程調用中的存儲方式等等。
在設計過程調用的原理時,人們採用了最低要求策略的方法。
在這裏插入圖片描述
概述:存放參數→調用add(add函數首地址)→add取出參數,執行相關過程→存放返回結果→返回main

過程概述

1 參數的傳遞
-參數通過stack傳遞
棧數據結構 這個部分是過程的棧幀(stack fram)在這裏插入圖片描述
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20200420111141621.png

  • P將入口參數(實參)存儲在Q能訪問到的地方
    2 轉移指令
    P保存返回地址(call指令下一條指令的地址),然後控制轉移到Q(EIP設置爲Q的首地址
    3 爲Q 分配空間, Q保存P的現場,爲自己的非靜態局部變量分配空間
    4 Q恢復現場,釋放空間,並
    提供一個返回值

    5 取出返回地址,控制轉移到P(ret指令)(EIP設置爲call指令下一條指令的地址
    保存現場的解釋:保存GPR中的內容,因爲調用過程和被調用過程用一套寄存器,需要標識哪些寄存器可用和使用規範。

寄存器使用約定(分配寄存器的規則)

  • P保存的寄存器:EAX EDX ECX (Q可以隨意使用,用完以後不需要恢復,ps:大廚從來不把原料歸到原位),如果P在Q返回後要使用,需要先提前告訴Q,先保存再恢復使用
  • 被調用者Q保存寄存器:EBX ESI EDI(必須先保存再使用,使用完記得恢復原樣)
  • EBP:幀指針寄存器 ESP:棧指針寄存器
    爲了減少準備和結束的開銷,Q儘量使用EAX ECX EDX
    通過改變esp的值增加或釋放空間
    調用過程棧和棧幀的變化
    在這裏插入圖片描述

入口參數的位置

實例1

在這裏插入圖片描述

  • 準備階段:
    pushl %ebp
    將EBP舊址壓棧,此時ESP指向R[EBP],
    movl %esp,%ebp將esp的值傳給ebp,此時兩個指針都指向棧頂,
    每個函數起始指令都是push和mov
    subl $24 %esp改寫esp的位置,提供空間存放參數和保留空間

  • 分配局部變量

  • 準備入口參數

  • call add

  • 返回地址的值在EIP中,返回參數在EAX中
    在這裏插入圖片描述

  • 返回地址是call指令下一條指令的地址

  • 入口參數按照從右到左存放

  • 按值傳遞&按地址傳遞

實例2

在這裏插入圖片描述
在這裏插入圖片描述

轉移控制

P到Q:EIP設置爲Q函數首地址
Q到P:call指令會把call指令下一條指令的地址壓入棧中
ret指令從棧中取出地址,將EIP設置爲該值

遞歸函數的實現

舉例

在這裏插入圖片描述
每次遞歸調用會增加棧幀,所以空間開銷大,時間開銷大
在這裏插入圖片描述
在這裏插入圖片描述

x86-64中的過程調用

在x86-64/Linux平臺上用以下命令執行編譯操作,得到與IA-32兼容的彙編指令代碼$ gcc -01 -S -m32 sample.c
在x86-64/Linux平臺上用以下命令執行編譯操作,得到x86-64彙編指令代碼$ gcc -01 -S -m64 sample.c(可以省略-m64)

棧的分配

32位系統在棧中傳遞,64位直接在寄存器中傳遞,將參數放入寄存器中
在這裏插入圖片描述

-通過通用寄存器傳送參數,很多過程不用訪問棧,故執行時間比IA-32代碼更短
-最多可有6個整型或指針型參數通過寄存器傳遞
-超過6個入口參數時,後面的通過棧來傳遞(32位直接使用棧)
-在棧中傳遞的參數若是基本類型,則都被分配8個字節

  • call (或Callq )將64位返址保存在棧中之前,執行R[rsp]←R[rsp]-8(64位架構返回地址一定是64位)
  • ret從棧中取出64位返回地址後,執行R[rsp]←R[rsp]+8
  • 64位架構中也有調用者保存寄存器和被調用者保存寄存器

數據傳送

x86-64中,大多數的數據傳遞都是通過寄存器實現的,P調用Q時,P的參數複製到適當的寄存器中,Q返回P時,P訪問R[%rax](32位中是eax)中的返回值
在這裏插入圖片描述

控制(更新中)

條件

if-else語句

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

  • 條件轉移指令
  • 無條件轉移指令 goto done

switch-case語句

在這裏插入圖片描述

推薦小鬼新歌《你最近還好嗎》,狠起來連自己都罵,每一天都是嶄新的一天!(吐槽:別人早安鈴都是叫早起,你的早安鈴是推薦新EP,我要換成尤膩膩的早安鈴了)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章