3

我在互聯網上搜索過所有內容,找不到適當的解釋如何返回工程?如何使用標記進行反向工程?

請問您能否解釋一下退款計劃的工作原理?它如何與標記一起使用?

我知道它有兩個主要類型的標記:

  1. 與下四在它
  2. 與下表中它

我發現this code,它們所採取一個輸入文件並用RISKI語言創建一個文件。

在他們的第一輥他們有:

PROGRAM : N FUNCTION M MAIN_FUNCTION 

,你可以看到,N和M是標記物(它們是空的卷)。

+0

你的意思是「回溯」嗎? –

+0

無返修,回溯還原 – boaz

回答

8

單通代碼生成對生成條件代碼有一個小問題。一個典型的if聲明:

if CONDITION then ALTERNATIVE_1 else ALTERNATIVE_2 

需要被編譯成這樣的:

compute CONDITION 
    JUMP_IF_TRUE label1 
    JUMP_IF_FALSE label2 

label1: 
    code for ALTERNATIVE_1 
    JUMP label3 

label2: 
    code for ALTERNATIVE_2 
    JUMP label3 

label3: 
    next statement 

但所產生的CONDITION代碼時,它是不知道哪裏label1label2是,當ALTERNATIVE_1ALTERNATIVE_2的代碼正在生成,但不知道其中的label3是。

這樣做的一種方法是使用標籤的符號名稱,如上面的僞代碼中所示,並在知道它們時填寫實際值。這需要在跳轉語句中存儲一個符號名稱,這會使數據結構複雜化(特別是,您不能只使用二進制彙編代碼)。它還需要第二遍,只是爲了填補跳躍目標。

(可能)更簡單的方法是隻記住跳轉語句的地址,並在目標地址已知時修補它。這就是所謂的「backpatching」,因爲你回去修補生成的代碼。

事實證明,在許多情況下,您最終會得到多個分支到同一個標籤。一個典型的例子是「短路」布爾運算符,如C系列的&&||運算符。例如,延長最初的例子:

if (CONDITION_1 and CONDITION_2) or CONDITION_3 then ALTERNATIVE_1 else ALTERNATIVE_2 

    compute CONDITION_1 
    JUMP_IF_TRUE label1 
    JUMP_IF_FALSE label2 

label1: 
    compute CONDITION_2 
    JUMP_IF_TRUE label3 
    JUMP_IF_FALSE label2 

label2: 
    compute CONDITION_3 
    JUMP_IF_TRUE label3 
    JUMP_IF_FALSE label4 

label3: 
    code for ALTERNATIVE_1 
    JUMP label5 

label4: 
    code for ALTERNATIVE_2 
    JUMP label5 

label5: 
    next statement 

事實證明,簡單的語言,只需要記住兩個不完整跳轉語句(通常被稱爲「真」與「假」)。因爲可能會有多個跳轉到同一個目標,所以這些跳轉實際上都是一個不完整的跳轉語句鏈表,其中目標地址用於指向列表中的下一個跳轉。因此,反向修補會遍歷列表,修補正確的目標並使用原始目標查找需要修補的先前語句。

你所謂的標記(它是yacc/bison被稱爲「Mid-Rule Productions」的一個實例)並不真正與backpatching有關。它們可以用於很多目的。在一次代碼生成中,通常有必要在規則中間執行一些操作,而反向計劃只是一個例子。

例如,假設if聲明,它會前CONDITION是在THENELSE條款的開始解析,然後backpatch需要初始化backpatch名單。 (在整個if聲明的解析結束時會觸發另一個補丁程序,但該補丁程序將處於規則的總結操作中。)

在規則中間執行操作的最簡單方法是插入中間規則動作,相當於在動作中插入一個空白的「標記」製作,如您指向的bison文件示例。