深入理解計算機系統——第三章—3.6控制

3.6 控制(control)

jump指令可以改變一組機器代碼指令的執行順序。

3.6.1 條件碼(condition code)

條件碼寄存器。
CF(carry flag): 進位標誌。最近的操作使最高位產生了進位。可用來檢查無符號操作的溢出。
ZF(zero flag)零標誌。最近的操作得出的結果爲零。
SF(signed flag)符號標誌。最近的操作得到的結果爲負數。
OF(overflow flag)溢出標誌。最近的操作導致一個補碼溢出——正溢出或負溢出。

標誌(flag 執行 效果
CF (unsigned) t < (unsigned) a 無符號溢出
ZF t == 0
SF t < 0 負數
OF a < 0 == b < 0 && (t < 0 != a<0 有符號溢出

leaq 指令不會改變任何條件碼,因爲它是用來進行地址計算的。
這裏寫圖片描述

3.6.2 訪問條件碼

條件碼通常不會直接讀取,常用的使用方法有三種:
1) 可以根據條件碼的某種組合,將一個字節設置爲 0 或者 1;
2)可以條件跳轉到程序的某個其他的部分;
3)可以有條件地傳送數據。
這裏寫圖片描述

3.6.3 跳轉指令

這裏寫圖片描述

3.6.4 跳轉指令的編碼

這裏寫圖片描述
這裏寫圖片描述

3.6.5 用條件控制來實現條件分析

將條件表達式和語句從C語言翻譯成機器代碼,最常用的方式就結合有條件和無條件跳轉。
這裏寫圖片描述
C語言中的 if-else 語句的通用形式模版如下:

if (test-expr)
    then-statement
else
    else-statement

對應彙編實現通常會使用下面這種形式。以C語言語法來描述控制流:

t = test-expr;
if (!t)
    goto false;
then-statement;
goto done;
false:
    else-statement;
done:

3.6.6 用條件傳送來實現條件分支

實現條件操作的傳統方法是通過使用控制的條件轉移(條件滿足,執行A;否則執行B)。
一種替代的策略是使用數據的條件轉移(在一定條件下,事先把條件結果列出來,根據條件直接選取數據結果來執行下一路徑)。
示例(ret 返回的參數存放在 %rax 中):
這裏寫圖片描述
分支預測錯誤的處罰
這裏寫圖片描述
條件傳送指令
這裏寫圖片描述
這裏寫圖片描述
如果條件分支中任意一個可能產生錯誤條件或者副作用,將會導致非法的行爲。
這裏寫圖片描述

3.6.7 循環

1. do-while 循環

這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述

2. while 循環

在這裏插入圖片描述
第一種翻譯方法(jump to middle
在這裏插入圖片描述
示例:
在這裏插入圖片描述
第二種翻譯方法(guarded-do
這裏寫圖片描述
示例:
這裏寫圖片描述
這裏寫圖片描述
有趣的特性。循環測試(彙編代碼的第9行)從原始C代碼的 n>1 變成了 n != 1 。編譯器知道只有當 n > 1時才進入循環,所以將 n1意味着n > 1或者n = 1。因此,測試n != 1 就等價於測試n >= 1。(本人未驗證)

3. for 循環

for 循環的通用格式:

for (init-expr; test-expr; update-expr)
    body-statement

等價於:

init-expr:
while(test-expr){
    body-statement
    update-expr;
}

跳轉到中間的策略 goto 代碼:

    init-expr;
    goto test;
loop:
    body-statement;
    update-expr;
test:
    t = test-expt;
    if(t)
        goto loop;

而 guarded-do 策略得到:

    init-expr;
    t = test-expr;
    if(!t)
        goto done;
loop:
    body-statement;
    t = test-expt;
    if(t)
        goto loop;
done:

這裏寫圖片描述
綜上所述,C語言中三種形式的所有循環——do-whilewhile、和for都可以用一種簡單的策略來翻譯,產生包含一個或多個條件分支的代碼。控制的條件轉移提供將循環翻譯成機器代碼的基本機制。

3.6.8 switch 語句

switch(開關)語句可以根據一個整數索引值進行多重分支(multiway branching)。
跳轉表是一個數組,表項 i 是一個代碼段的地址,這個代碼段實現當開關索引值等於 i 時程序應該採取的動作。
示例:
這裏寫圖片描述
這裏寫圖片描述
跳轉表
這裏寫圖片描述

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