LCC編譯器的源程式分析 32 for迴圈語句

2021-04-13 02:39:59 字數 1914 閱讀 8797

c

語言中的

for語句使用最為靈活,不僅可以用於迴圈次數已經確定的情況,而且可以用於迴圈次數不確定而只給出迴圈結束條件的情況。因此,這個語句的使用頻率是最高的,當然它的處理情況比上面兩種迴圈要複雜一些。它的形式如下:

for(

表示式1;

表示式2;

表示式3) 語句

1 它的執行過程是先求解表示式

1的值,然後再計算表示式

2的值。如果其值為真,就執行語句

1,然後再執行表示式

3。如果其值為假,就直接跳出迴圈不再執行語句

1和表示式

3。如果在

c++裡還會有作用域的範圍不同樣的。

下面就是

lcc處理

for迴圈的**:

#023  case for:     

#024         forstmt(genlabel(4), swp, lev + 1);

#025         break; 第

24行是呼叫函式

forstmt

來處理for

語句。

而函式forstmt

的**如下:

#001 static void forstmt(int lab, swtch swp, int lev)

#002 ', 0 };

#031         test(')', stop);

#032  }

#033  第

26行是判斷第三個表示式是否存在,如果存在就呼叫函式

texpr

來處理第三個表示式。如果不存在,就需要處理右括號了。

#034  if (e2)

#035  

#040   第

34行是判斷第二個表示式是否存在,如果存在就查詢迴圈是否需要執行一次,如果不需要執行就跳到第三個標號。

#041  definelab(lab);

#042  statement(lab, swp, lev);

#043  

#044  definelab(lab + 1);

#045  definept(&pt3); 第

41行是定義第乙個標號。 第

42行是處理迴圈體的語句1。

第44行是定義第二個標號。

#046  if (e3)

#047         walk(e3, 0, 0);

#048  

#049  if (e2)

#050  

#056  else

#057  

#061 

#062  if (findlabel(lab + 2)->ref)

#063         definelab(lab + 2);

#064 

#065 } 第

46行和第

47行是計算第三個表示式。 第第

49行到第

55行是處理第二個表示式,如果第二個表示式值為真就需要跳轉到第乙個標號執行語句。 第

52行是生成第

4個標號,由於不能判斷是否需要執行一次時,就需要計算表示式的值,才能決定。 第

57行到第

60行是沒有第二個表示式,所以無條件跳到第乙個標號那裡繼續執行語句1。

通過執行上面的**就會生成下面形式的彙編**:

表示式1

標號1:語句1 標號

2:表示式3

標號4:如果表示式

2值不等於

0 就跳到標號1

標號3:

上面的優化**,如果當常量判斷表示式

2要執行一次時,就直接從標號

1開始執行了,不用跳到標號

4作一次判斷。如果不是常量判斷出來的,就需要多乙個跳轉,先跳到標號

4那裡執行,作表示式

2的計算再作出選擇。

LCC編譯器的源程式分析 12 13

語法分析是比較複雜的處理,下面再來分析乙個例子,它的 如下 typedef unsigned short wchar t typedef wchar t wint t 第一句語句在lcc裡的處理,前面已經解釋清楚,主要生成wchar t儲存符號表裡,並且記錄這個id的型別屬性。那麼第二句是怎麼樣通過...

LCC編譯器的源程式分析 18 19

lcc編譯器的源程式分析 19 全域性函式的定義 函式定義funcdefn處理裡,已經準備好呼叫引數和引數返回,接著就是呼叫全域性函式宣告來處理。如下面的 132 宣告函式。133 cfunc dclglobal sclass,id,ty,pt 134 上面的 是處理函式全域性定義。現在就去就分析d...

LCC編譯器的源程式分析 20 復合語句

在 c語言裡,有一種語句叫做復合語句。它是由 把一些語句括起來的,如下面的例子 在lcc 裡處理這樣的復合語句的函式是 compound 它在上面函式定義函式 funcdefn 是這樣呼叫的 150labels table null,labels 151stmtlabs table null,lab...