我在互聯網上搜索過所有內容,找不到適當的解釋如何返回工程?如何使用標記進行反向工程?
請問您能否解釋一下退款計劃的工作原理?它如何與標記一起使用?
我知道它有兩個主要類型的標記:
- 與下四在它
- 與下表中它
我發現this code,它們所採取一個輸入文件並用RISKI語言創建一個文件。
在他們的第一輥他們有:
PROGRAM : N FUNCTION M MAIN_FUNCTION
,你可以看到,N和M是標記物(它們是空的卷)。
我在互聯網上搜索過所有內容,找不到適當的解釋如何返回工程?如何使用標記進行反向工程?
請問您能否解釋一下退款計劃的工作原理?它如何與標記一起使用?
我知道它有兩個主要類型的標記:
我發現this code,它們所採取一個輸入文件並用RISKI語言創建一個文件。
在他們的第一輥他們有:
PROGRAM : N FUNCTION M MAIN_FUNCTION
,你可以看到,N和M是標記物(它們是空的卷)。
單通代碼生成對生成條件代碼有一個小問題。一個典型的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
代碼時,它是不知道哪裏label1
和label2
是,當ALTERNATIVE_1
和ALTERNATIVE_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
是在THEN
和ELSE
條款的開始解析,然後backpatch需要初始化backpatch名單。 (在整個if
聲明的解析結束時會觸發另一個補丁程序,但該補丁程序將處於規則的總結操作中。)
在規則中間執行操作的最簡單方法是插入中間規則動作,相當於在動作中插入一個空白的「標記」製作,如您指向的bison文件示例。
你的意思是「回溯」嗎? –
無返修,回溯還原 – boaz