組合語言中迴圈語句的實現
一、概述
C語言中有許多不同的結構,比如if-else、do-while、while、for、swich等等,這些結構的彙編實現都是一層一層在前者的基礎上進行構建的。比如if-else是基於jmp命令實現的,do-while是基於if-else的彙編結構的,而while又是基於do-while的。所以說jmp在彙編中有著特別重要的作用,它是實現多種C語言結構的基礎。
if-else依賴於跳轉指令;
do-while迴圈先被轉換為if-else,然後再進行翻譯,其中使用較多的是比較命令cmp和條件跳轉指令;
while迴圈先被轉化為 if 和 do-while的結合體,然後再分別進行翻譯;
for迴圈與while迴圈非常類似,僅是多了一個賦值語句而已,翻譯過程與while類似,但要注意continue的處理,謹防處理不當而使得語句陷入死迴圈。
二、jmp命令
三、if-else的組合語言形式
.
四、do-while的彙編形式
大多數彙編器根據一個迴圈的do-while形式來產生迴圈程式碼,其他的迴圈會首先轉換成do-while形式,然後再進行編譯,所以do-while迴圈是所有迴圈結構的基礎。它的彙編翻譯如下形式
五、while迴圈
將while迴圈翻譯成機器程式碼有很多種方法,一種常見的方法,也是GCC採用的方法,是使用條件分支,在需要時省略迴圈體的每一次執行,從而將程式碼轉換成do-while迴圈,具體例項如下:
六、 for迴圈
首先可以將for迴圈轉換為while迴圈,然後再按照上面的方法,最終完成for迴圈到機器程式碼的轉換。但在這裡需要特別注意的是,當迴圈中出現有continue時,一定要注意控制變數的自增或自減操作,否則會導致無限迴圈。
比如將如下C語句程式碼翻譯成機器語言:
int sum = 0;
int i;
for(i = ; i < 10; i++){
if (i & 1)
continue;
sum += i;
}
如果按照如下的方式進行轉換的話,continue語句會阻止索引變數i被修改,導致程式碼無限迴圈:
int sum = 0;
int i = 0;
while (i < 10)}
if (i & 1)
continue;
sum += i;
i++;
}
所以,正確的翻譯方法為:
int sum = 0;
int i = 0;
while (i < 10)}
if (i & 1)
goto update;
sum += i;
update:
i++;
}