程式的機器級表示(二)

2021-07-27 05:55:20 字數 1927 閱讀 6071

以上操作,我們只考慮了直線**的行為,即指令按順序執行。但是還有一些**,比如條件語句、迴圈語句和分支語句,要求有條件的執行,這時需要根據資料測試的結果來改變條件碼,結合跳轉指令決定操作執行的順序。

條件傳送指令

實現條件操作的傳統方法是利用控制的條件轉移。當條件滿足時,程式沿著一條執行路徑進行,而當條件不滿足時,就走另一條路徑。這種機制簡單而通用,但是在現代處理器上,可能效率不高。

資料的條件轉移是一種替代的策略。這種方法先計算乙個條件操作的兩種結果,然後再根據條件是否滿足從而選取乙個。條件傳送指令更好地匹配了現代處理器的效能特性。

看如下例子:

條件表示式同條件語句相似。關鍵就在於彙編**第8行的cmovl指令,這條指令除了只在指定的條件滿足時才執行資料傳送之外,它的語法與mov指令的相同。

考慮下面的條件表示式和賦值的通用形式:

v = test-expr

?then-expr:lese-expr;

編譯器產生的**,條件轉移形式:

if (!test-expr)

goto false;

v = then-expr;

goto done;

false:

v = else-expr;

done:

基於條件傳送的**:

vt = then-expr;

v =else

-expr;

t = test-expr;

if(t) v = vt;

這個序列中的最後一條語句是用條件傳送實現的——只有當測試條件t滿足時,vt的值才會被複製到v中。

現代處理器通過使用流水線來獲得高效能,即重疊連續指令的步驟。當機器遇到條件跳轉時,它常常不能確定是否要進行跳轉。處理器會進行分支**,但是**錯誤要求處理器丟掉它為跳轉指令後所有指令已經做了的工作,招致很嚴重的懲罰,導致效能下降。但是使用條件傳送也不是總會改進**的效率。例如,如果then-expr或者else-expr的求值需要大量的計算,那麼當相對應的條件不滿足時,這些工作就白費了。編譯器必須考慮浪費的計算和由於分支**錯誤所造成的效能處罰之間的相對效能。

switch語句

switch語句可以根據乙個整數索引值進行多重分支。它通過跳轉表實現。

其中jt就是跳轉表。可以觀察到,跳轉表對重複情況的處理就是簡單地對表項4和6用同樣的**標號(loc_ d),而對於缺失情況的處理就是對表項1和5使用預設情況的標號(loc_def)。

上述**的彙編**如下:

執行switch語句的關鍵步驟是通過跳轉表來訪問**位置,彙編**中,跳轉錶用以下宣告:

這些宣告表明,在「.rodata」(唯讀資料,read-only data )的目標**檔案的段中,應該有一組7個「long」(4個位元組),每個字的值都是與指定的彙編**標號相關的指令位址。標號.l7標記出這段分配位址的起始。

使用跳轉表是一種非常有效的實現多重分支的方法。在我們的例子中,程式可以只用一次跳轉表引用就分支到5個不同的位置;當switch語句有上百種情況的時候,也可以只用一次跳轉表訪問去處理。

程式的機器級表示二(控制)

目錄 1.條件碼 2.跳轉指令 3.條件傳送指令 4.switch語句 實現有條件的行為 lea mov指令不設定條件碼 比較和測試指令 cmp類似 sub 指令的行為,只設定條件碼而不更新目標暫存器。test類似and,只設定條件碼而不更新目標暫存器。訪問條件碼 用法 條件碼組合,設定某個位元組 ...

程式的機器級表示

三種 立即數 常數值,在att格式的彙編 中,書寫格式是 整數,如 123 0x12 暫存器 如 32位的 eax 16位的 ax 8位的 al 儲存器引用 mov 同等傳送,即倆者的大小一致 如 movb byte,movew word,movel longword dw movs movz 不同...

程式的機器級表示

32位和64位 instruction system architecture 程式計數器pc eip 整數暫存器 8個每個32位 有的用來記錄狀態,有的用來儲存臨時資料,區域性變數,返回值 3.條件碼暫存器 指標都是雙字 char short long 其他4位元組 movb movw movl ...