Remove ads
来自维基百科,自由的百科全书
在電腦編譯器架構中,基本塊(basic block)是一段線性的程式碼,只能從這段程式碼開始處進入這段程式,沒有其他程式碼會跳躍進入這段程式,只能從這段程式碼最後一行離開這段程式,中間沒有其他程式碼會跳躍離開這段程式[1][2]。這種程式的限制使得基本塊非常好分析[3]。編譯器處理程式時,會在分析程序中,將程式分解為所有基本塊的組合。在控制流圖中,基本塊是控制流圖中的節點。
此條目需要补充更多来源。 (2020年7月) |
以下是一段QuickBASIC程式,程式中的前二行(DO之前的程式碼)即為基本塊。
INPUT "What is your name: ", UserName$
PRINT "Hello "; UserName$
DO
INPUT "How many stars do you want: ", NumStars
Stars$ = STRING$(NumStars, "*")
PRINT Stars$
DO
INPUT "Do you want more stars? ", Answer$
LOOP UNTIL Answer$ <> ""
Answer$ = LEFT$(Answer$, 1)
LOOP WHILE UCASE$(Answer$) = "Y"
PRINT "Goodbye "; UserName$
基本塊的程式有以下特點:
因為上述特點,基本塊中的程式,只要執行了第一行,後面的程式碼就會依序執行,每一行程式都會執行一次[4][5]。
以下是更型式化的定義一串的指令屬於基本塊的方式:
此定義會比一開始較直觀定義的範圍更廣。例如,此定義可以允許程式碼中間有無條件的跳躍,只要跳躍目的的程式碼不是其他跳躍的目的即可。使用此定義,在產生基本塊的演算法中,會比較容易產生基本塊。
在執行某一基本塊最後一行之後,可能會執行的基本塊稱為「後繼」(Successor),而執行此基本塊之前,可能會執行的基本塊稱為「前驅」(Predecessor)。會跳到基本塊啟始程式的程式碼可能不止一處。
若要由一串的指令中產生基本塊,其演算法如下:程式先分析指令,找到「基本塊的邊界」,基本塊的邊界是指可能會開始一個基本塊(因為是其他流程控制指令的跳躍目標)或是結束一個基本塊的指令(因為有流程控制指令,可能會跳躍到其他的基本塊)。因此,指令列表會因為這些「基本塊的邊界」而切割成幾段,這幾段就是基本塊。
上述方式不一定能找到(在型式化定義下)最大的基本塊,不過多半而言都已足夠了(最大的基本塊是指基本塊無法在不違反規則的情形下,和鄰近基本塊合併,形成更大的基本塊[6])。
輸入:一串指令(多半是三位址碼)[7]。 輸出:一串的基本塊,其中每一個三位址碼都恰好在一個基本塊內。
步驟1:找到程式碼中的啟始指令(leader)。滿足以下任何一項的就是啟始指令:
步驟2:從啟始指令開始,一直往下檢查,直到找到下一個基本塊的啟始指令為止,從啟始指令開始,到下一個基本塊的啟始指令之前的程式碼就是對應啟始指令的基本塊。
每一個基本塊都會有一個啟始指令。
以下的程式碼會結束一個基本塊:
longjmp
指令及exit
指令。以下的程式碼會開始一個基本塊:
因為流程控制無法越過基本塊的結尾,在找到基本塊之後,有些基本塊邊界可能要調整。特別是「貫穿」(fall-through)的條件分支需要改為傳統二路的條件分支,丟出异常的函數後面需要加上無條件的跳躍。這些調整可能需要在其他基本塊的開始處加上標記,表示是無條件跳躍的目標。
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.