呢篇文係一篇好文。想知更多,請撳呢個掣。

組合語言

出自維基百科,自由嘅百科全書
跳去導覽 跳去搵嘢

摩托羅拉 MC6800 組合語言碼;睇到段碼混合咗數字同羅馬字。

組合語言粵拼zou2 hap6 jyu5 jin4英文assembly language,簡稱「asm」),又有叫匯編語言,係一類低級(low-level)程式語言,特徵係喺結構上似機械語言(machine language;部電腦內部真正處理緊嘅語言)得嚟,又會用羅馬字母[1][2]:組合語言通常會用羅馬字母代表機械語言入面嗰啲命令,而要處理嘅輸入就會用數字代表,唔似得機械語言噉,吓吓都淨係用 1 同 0 嘅數值代表嗮所有嘢[3][4]

舉返個例說明:喺 Zilog Z80處理器嗰度,「00000101」呢段機械碼會令到粒 CPU 做「將 B 處理器暫存器入面嗰個數值下降 1」嘅運算,而同一個命令用組合語言寫嘅話會係「DEC B」-喺組合語言嗰串命令當中見到有「DEC」呢三個羅馬字母,代表咗英文字「decrement」(指「令某啲嘢數值下降」噉解)。組合語言對羅馬字母嘅使用令到用呢啲語言寫成嘅碼(對一般人嚟講)易睇過機械語言碼好多[5][6]

話雖如此,組合語言都有「兩頭唔到岸」嘅缺點:喺一般嘅應用當中,電腦內部處理嘅係機械語言,電腦係唔曉直接讀組合語言嘅,所以喺用親組合語言寫程式嗰陣,個用家梗要有個組合器(assembler)將段組合語言碼轉化做電腦識直接睇嘅機械語言,即係唔似得機械語言碼噉,可以直接攞嚟俾電腦行[7];另一方面,組合語言又唔似得高級語言(high-level programming language)噉有普遍性-每一款組合語言都係要喺某啲特定嘅電腦系統架構作業系統(operating system)上先會行到[8],而相比之下,好似係 Java 或者 Python 等嘅高級語言一般都可以用落去多個平台上面,淨係需要有啱用嘅編譯器(compiler)將佢哋翻譯俾部電腦睇就得[6]

基礎[編輯]

典型嘅機械語言齋靠一大柞 0 同 1 嚟表達,對一般人嚟講好難明。
睇埋:處理器 (運算)電腦記憶體同埋寄存器

機械語言[編輯]

內文:機械語言

機械語言(machine lanaguage)係電腦內部直接處理嗰種語言。機械語言係最低級(low-level)[註 1]程式語言-淨係用數字表達嗮所有嘢,而組成一段機械碼嘅數字會包含嗮「要用啲乜嘢數據」同「要做啲乜嘢作業」等嘅資訊。舉個例說明:假想而家有款機械語言,

  • 款語言嘅每段命令都由 18 個數字組成,呢 18 個數字每一個都一係 1 一係 0(每一個呢啲數字成一個 bit),
    • 最頭嗰 7 個數字用二進制表達數據 A
    • 跟住嗰 7 個數字用二進制表達數據 B
    • 最尾嗰 4 個數字就表達要做乜(呢段就係所謂嘅行動碼;opcode)-0000 代表,0001 代表等等。

於是喺用呢種語言寫成嘅源碼入面,「0000011 0000100 0000」呢段碼係叫電腦計 3(用二進制寫係 11)加 4(用二進制寫係 100)嘅結果出嚟[9][10]。有關機械語言嘅物理實現,可以睇吓電子工程邏輯門等嘅電腦硬件技術。

組合句法[編輯]

組合語言大致上就係用羅馬字母嘅機械語言,用咗記憶術表達想部電腦行嘅指示:組合語言會用羅馬字母串表達機械語言當中嘅每一個命令或者行動碼,通常亦會用同樣嘅手法表達埋要用嘅資訊喺邊個暫存器(register)同位元欄(bit field)等嘅資訊,並且好多時會掕埋一個或者多個運算數(operand;指要運算嗰啲數值)[6]

舉個例說明,例如家吓個用家想叫部電腦計「3 + 2」嘅結果,「加」就係要做嗰個命令,喺部電腦嘅機械碼會有個相應嘅行動碼,而 3 同 2 就係運算數。多數嘅組合器(assembler;將段組合語言碼轉化做電腦識睇嘅機械語言)都容許用家運用有名嘅常數、暫存器同埋記憶嘅位置等嘅資訊,所以個用家唔使用人手噉做一啲重複性嘅作業,亦都唔使睇淨係用 1 同 0 寫成嘅機械碼[6][7]

以下係一啲典型嘅用組合語言寫嘅語句[11]

INC COUNT        ; 將而家喺記憶入面嗰個變數嘅數值「提高」(increment),而 count 係要提高幾多。

ADD AH, BH       ; 將 BH 暫存器入面嗰個數值加落去 AH 暫存器入面嗰個度。

AND MASK1, 128   ; 同變數「MASK1」以及「128」呢個數字做 AND 嘅作業。

ADD MARKS, 10    ; 加 10 落去變數「MARKS」嗰度。

MOV AL, 10       ; 「搬」(move)10 呢個數字去 AL 暫存器嗰度。

視乎系統結構,呢啲元素可以結合埋一齊嚟整更加複雜嘅命令。

例子 1

舉個具體例子說明,以下呢段碼會叫一個 X86 或者 IA-32 處理器去將一個 8 bit 咁長嘅數值搬去個暫存器嗰度。呢個命令用二進制嘅機械語言寫嘅話係「10110」,而呢個命令跟住仲要掕住第段數字表示要用邊一個暫存器嚟做,例如 AL 暫存器嘅碼係「000」,所以跟住呢段機械碼會叫部電腦將數據 0110001 入落去 AL 暫存器嗰度[12]

10110000 01100001

呢段碼有得用十六進制嚟表示,等段嘢對一般人嚟講易睇啲:

B0 61

喺呢段碼入面,「B0」代表咗行動碼,叫部電腦做「將跟住嗰個數值複製,再擺落去 AL 嗰度」,而「61」係用十六進制寫嘅「0110001」(呢個數用十進制寫係「97」)。8086 系列嘅組合語言仲會俾用家用「MOV」(英文字「move」嘅簡寫)嚟表達呢個命令,等段碼對於人類嚟講更加易睇,即係好似以下噉樣:

MOV AL, 61h       ; 將「97」嘅數值嘅二進制版本入落去 AL 嗰度。

喺第啲組合語言入面,同一段字(「MOV」)可能會有唔同-但類似-嘅意思,好似係「將某某數據搬去某個暫存器嗰度」呀噉。又有啲可能會將個命令分開或者合拼,例如係用「MOV」代表嗮所有數據嘅移動(無論係喺暫存器之間搬定係點),又或者用唔同嘅命令代表「由記憶體去暫存器」同「由暫存器去記憶體」... 等等。

例子 2

「1011000」(十六進制:B0)係 X86 當中嘅一段行動碼,會將一個 8 bit 長嘅數值搬去 AL 暫存器嗰度,「1011001」(十六進制:B1)會將個數值搬去 CL 暫存器,而「1011010」(十六進制:B2)會將個數值搬去 DL 暫存器,即係好似以下呢段碼噉[12]

MOV AL, 1h        ; 將「1」嘅數值嘅二進制版本入落去 AL 嗰度。
MOV CL, 2h        ; 將「2」嘅數值嘅二進制版本入落去 CL 嗰度。
MOV DL, 3h        ; 將「3」嘅數值嘅二進制版本入落去 DL 嗰度。
例子 3

「MOV」呢個命令可以做得再複雜啲,好似以下嘅碼噉[13]

MOV EAX, [EBX]	  ; 記憶體之間嘅數據移動,將「EBX」嗰個位置入面嗰 4 位元組嘅數據搬去「EAX」嗰個位置度。
MOV [ESI+EAX], CL ; 將 CL 嘅內容搬去「ESI+EAX」嗰個位置度。

語言設計[編輯]

睇埋:程式語言理論

三大元素[編輯]

組合器嘅人响將命令分類同埋所用嘅命名法等方面好多樣化。不過,無論係邊款組合語言邊個設計師,一款典型嘅組合語言喺句法(syntax)上都會有三款命令用嚟定義個程式要乜[6][14][15]

  • 用羅馬字代表嘅行動碼(opcode)、
  • 類行動碼(pseudo-opcode)、
  • 數據定義(data definitions):數據定義會定義要處理嘅數據嘅種類(例如係「數值」同「字母」等嘅種類)同埋長度(等部電腦知要預留幾多記憶體空間嚟儲件數據)等嘅資訊。呢啲命令亦都可以用嚟定義啲數據係咪可以由外來嘅程式(指分開噉組合嘅程式)處理,定係淨係可以喺嗰個程式入面用。睇埋運算數
INC COUNT        ; 將而家喺記憶入面嗰個變數嘅數值「提高」;
;行動碼:INC;
;數據定義:COUNT;

ADD AH, BH       ; 將 BH 暫存器入面嗰個數值加落去 AH 暫存器入面嗰個度;
;行動碼:ADD;
;數據定義:AH 同 BH;

MOV AL, 10       ; 搬10 呢個數字去 AL 暫存器嗰度;
;行動碼:MOV;
;數據定義:AL 同 10;

行動碼[編輯]

內文:行動碼

行動碼(opcode)係指段命令當中教部電腦「要做乜運算」嗰橛。組合語言入面嗰啲命令一般都係好簡單嘅,唔似得高級語言入面嗰啲噉。普遍嚟講,喺程式編寫上,記憶術(mnemonic)係指某個電腦識執行嘅機械碼用符號(而唔係 0 同 1)表達嘅名,例如係正話提咗嘅例子 1 入面嘅 X86 命令「將跟住嗰個數值複製,再擺落去 AL 嗰度」噉,

  • 段嘢本身係一個部電腦識得執行嘅命令;
  • 機械語言當中嘅行動碼係「10110」;
  • 喺嗰款組合語言當中嘅記憶術係「MOV」(英文「move」嘅簡寫,意思係「搬」或者「郁」噉解);

是但搵款組合語言嚟睇,同款語言對應嘅機械語言嘅每款命令都會有個記憶術[註 2][16]。多數嘅命令都會掕住若干個運算數,運算數可以代表要計嘅數值又得、代表儲住要用嘅數值嘅暫存器嘅位置又得、或者要用嘅數值喺部電腦嘅記憶嘅位置都得[17]

有陣時,一款組合語言會有延伸嘅行動碼嚟表達一啲結合咗多個命令嘅複雜命令。舉個例說明,有好多 CPU 都係冇 NOP 命令-呢個命令叫部電腦唔好做任何嘢,好多時俾人攞嚟控制第啲命令喺乜嘢時間行;但有一啲細啲、可以結合埋一齊做 NOP 嘅命令;喺 8086 系列嘅 CPU 當中,xchg ax,ax 呢行命令俾人用嚟做 nop,而 nop 呢段嘢嚴格嚟講唔算係呢啲 CPU 入面嘅命令。某啲反組合器識得認呢段碼,會將 xchg ax,ax 解碼做 nop。呢啲唔淨只代表一個命令,而係代表咗多個命令嘅組合嘅記憶術就係所謂嘅延伸記憶術(extended mnemonics)[18],SPARC 架構嗌呢啲記憶術做合成命令(synthetic instrcution)[19]

類行動碼[編輯]

內文:類行動碼

類行動碼(pseudo-opcode)係指一啲由個用家俾去個組合器嘅命令,叫個組合器做一啲「翻譯組合碼」以外嘅作業[20]。呢啲指示會影響到個組合器嘅運作,控制個組合器內部嘅參數,例如係個組合器「用乜訊號代表邊個邊個組合碼命令」呀噉。類行動碼嘅名通常都係以一個點(.)做開頭嘅-呢樣嘢幫手令啲用家一睇就知呢啲碼同機械碼命令唔同[21][22]

類行動碼可以好有用。呢啲碼可以令一個程式嘅組合受制於程式員俾嘅參數,即係叫個組合器「喺呢個情況噉樣組合,而喺第個情況用第個方法組合」,令到有陣時同一個程式可以用唔同方法組合,增加組合器嘅用途;另一方面,類行動碼又可以用嚟操控一個程式點樣呈現,令個程式對於人類嚟講易睇啲;類行動碼嘅仲可以用嚟保留空間去儲起個組合器嘅執行期(run time)等嘅資訊,等個程式員有得做有關「個組合器用咗幾耐時間做一次翻譯」方面嘅分析[20]

同大多數嘅電腦語言一樣,組合語言俾用家喺個程式嘅源碼嗰度加啲注釋(comment)落去-即係喺啲命令後面有啲用人類語言寫、個組合器喺組合段碼嗰陣會忽略嘅句子(即係好似下面嗰段碼入面嗰啲灰字)。呢啲句子幫到程式員手令到佢哋寫嘅源碼更加易讀,例如一個程式員可以喺一行命令後面加個注釋,用淺白嘅語言講清楚嗰行命令處理嗰個變數有乜嘢重要性。呢啲注釋會令到下一手處理呢段源碼嘅程式員能夠一睇就明嗰行命令係做乜嘢目的嘅[20]

MOV CL, 34h       ; 呢段灰色嘅字係注釋-個組合器係設計好咗會忽略「;」後面嘅碼,所以呢段灰字部電腦唔會處理,但係程式員可以用佢嚟解釋俾下一手程式員知呢段碼有乜嘢作用。

組譯風格比較[編輯]

x86/amd64 組譯命令嘅兩大風格分別係 Intel 組譯同 AT&T 組譯,分別由 Microsoft Windows/Visual C++GNU/Gas 用(Gas 亦可以用 Intel 組譯風格):

項目 Intel 風格 AT&T 風格
運算元(operand)順序 目標運算元喺前 源運算元喺前
暫存器嘅名 原樣 字頭加「%」
立即數 原樣 字頭加「$」
十六進制立即數 字尾用「b」同「h」分别代表二進制同十六進制
對於十六進制字母開頭嘅字首要加「0」
字首加「0x」
存取記憶體長度嘅表示 字首加「byte ptr」,「word ptr」,「dword ptr」 字尾加 b、w、l 代表位元組、字、長型
參照全局或者靜態 var 嘅值 [_var] _var
參照全局或者靜態變數 var 嘅位址 _var $_var
參照局部變數 需要基於棧指標(ESP)
記憶體直接尋址 seg_reg: [base + index * scale + immed32] seg_reg: immed32 (base, index, scale)
暫存器間址 [reg] (%reg)
暫存器變址尋址 [reg + _x] _x(%reg)
立即數變址尋址 [reg + 1] 1(%reg)
整數陣列尋址 [eax*4 + array] _array (,%eax, 4)

組合器[編輯]

內文:組合器

組合器(assembler)係用組合語言寫程式實要用嘅嘢,組合器係一啲特別嘅程式,負責將用組合語言寫成嘅源碼轉化做電腦識睇嘅機械碼:一段電腦會識行嘅機械碼會完全用 1 同 0 表達嗮所有資訊-包括行動碼、運算數同埋啲運算數嘅位置;個組合器會將組合碼入面嗰啲羅馬字母轉化做相應嘅機械碼,亦都會計返好啲常數表達同埋解決記憶體嘅位置以及其他嘢嘅名。組合器會用某啲名代表個程式入面嘅物體,唔似得機械語言噉,等個用家唔使吓吓都計同人手噉更新啲嘢嘅位置[20]。例:

  • 入落組合器嘅輸入:MOV R3, #15
  • 組合器俾出嘅輸出:1100 1010 1011 0011

組合器呢家嘢早喺 1950 年代,有字嘅電腦介面啱啱出現嗰陣時經已開始有,同 FortranCOBOL、同埋 LISP 呢啲早期程式語言同期,而且喺嗰時因為易寫過高級語言嘅編譯器而頗受歡迎-正如頭先提到,組合語言喺結構上好似機械語言,好多時組合語言啲命令都只不過係用咗羅馬字母表達嘅機械語言命令,組合語言入面嗰啲命令好多都同某啲機械語言嘅命令有 1 對 1 嘅關係,所以要將組合碼翻譯做機械碼好容易[20]

功能
  • 有陣時,同一個 CPU 或者命令集會有好幾個命令句法嚟應付唔同嘅組合器。舉個例說明,喺 X86 型嘅處理器當中,一條「叫部電腦將記憶數據加落去個暫存器嗰度」嘅命令用 Intel 嘅句法寫可能係 add eax,[ebx],而用 GNU 組合器用嘅 AT&T 嘅句法寫就係 addl (%ebx),%eax。雖然呢啲唔同句法寫嘅命令望落唔同,但佢哋轉化咗做機械碼嗰陣好多時都係一樣樣嘅。有陣時同一個組合器可能會有幾個唔同模式嚟幫手翻譯唔同嘅句法嘅組合碼[20]
  • 有啲組合器仲有能力做一啲簡單嘅命令集特定嘅編譯器最佳化(optimization)-最佳化係指將個編譯器嘅某啲特徵最大化或者最小化,例如係某啲組合器曉將個編譯器行嗰陣霸嘅記憶體量最小化,等部機行起上嚟順暢啲。周圍都搵得到嘅 X86 組合器就係一個具體嘅例子,呢啲組合器多數都曉喺俾用家要求嗰陣時跳過若干行嘅指示,有啲仲曉做簡單嘅重新排序或者插入新指示。

要睇幾多次[編輯]

組合器大致上可以按「行嗰陣要睇段源碼幾多次」嚟分做兩大類[23]

  • 睇一次組合器(one-pass assembler)會將段源碼睇一次,跟手就可以出到佢要出嘅輸出。喺段源碼行過之前用咗嘅符號都需要改返啱,話俾部機聽要覆蓋(overwrite)一個之前用過嘅(記憶體入面嘅)位,並且將呢個位攞嚟儲嗰個新嘅變數。
  • 睇多次組合器(multi-pass assembler)會整個表出嚟,列嗮所有嘅符號同埋佢哋喺第一次睇段碼嗰陣嘅數值出嚟,再用個表嚟整碼。

傳統上用睇一次組合器嘅原因係因為呢啲組合器唔使同一段源碼睇幾次,所以做起嘢上嚟好快,組合時間(assembly time;評估組合器效率嘅重要指標之一)短-睇第二次就要重新讀過段源碼一次,呢樣嘢要用舊式嘅電腦(靠讀一段寫咗喺帶上面嘅源碼嘅電腦)做可以撈絞得好交關。但由廿一世紀初開始,電腦經已有龐大嘅記憶體,能夠有足夠嘅空間做嗮所有必需嘅處理而唔使讀帶,所以更加穩陣同埋做起某啲作業上嚟快啲嘅睇多次組合器開始受到重視[23]

例子說明

喺以下呢段組合碼當中,一個睇一次組合器喺處理 S2 嗰行命令嗰陣已經能夠知道 BKWD 嘅位置,但喺處理 S1 嗰行命令嗰時唔會知道 FWD 嘅位置,所以要靠估嚟決定要預留幾多記憶體嘅位置。相比之下,一個睇兩次嘅組合器會喺第一次睇段碼嗰陣知道兩個物件嘅位置,並且喺第二次讀碼嗰陣處理。

S1   B   FWD
...
FWD   EQU *
...
BKWD   EQU *
...
S2   B   BKWD

組合器類別[編輯]

  • 宏組合器(macro assembler):會用特定嘅名嚟表達某啲特定嘅組合語言命令,例如係用「swap」(英文「交換」噉解)代表一個令某兩個變數數值互換嘅命令,等個用家有得直接打「swap」就可以直接將嗰串命令入落去第段碼嗰度-唔使吓吓都成串命令打一次。好多組合器亦都內置宏組合器。
  • 微組合器(micro assembler):係一個用嚟準備微程式嘅程式,呢啲微程式嘅作用係要控制部電腦當中啲低級嘅作業。
  • 交叉組合器(cross assembler):組合器一種,負責令一段組合碼喺另一個(同嗰段組合碼所屬嗰個系統唔同嘅)電腦或者作業系統上面行;交叉組合器令到用家有得為一啲本身冇能力支援軟件發展嘅系統寫程式。喺呢個情況下,個用家可以將要行嗰段碼(目的碼)用某啲方法-例如係唯讀記憶體-轉移去個目標系統嗰度。
  • 高級組合器(high-level assembler):一個提供類似高級程式語言嘅命令嘅程式,高級組合器會俾個用家用一啲進級嘅控制結構命令(例如係 IF/THEN/ELSE)同埋一啲進級嘅數據類[24]
  • 反組合器(disassembler):可以話組合器嘅相反,會負責將用機械語言寫嘅碼翻譯做特定嘅組合語言[25]

... 等等。

支援結構化編程[編輯]

睇埋:結構化編程

高級語言入面常見、用嚟做結構化編程(structured programming)嘅命令多數都可以用簡單嘅組合語言命令砌出嚟[26]。例如:

條件運算式[編輯]

睇埋:條件運算式

條件運算式(conditional statement)係高級語言常用嘅命令之一。一個條件運算式會指明一個條件同埋包含一柞命令,而如果個條件成立,噉佢就會叫部電腦做佢包含嗰柞命令,好似係以下呢段 C 嘅碼噉[27]

if (ax < bx) { // 如果 ax 細過 bx...
    x = -1; // 將 x 設做 -1。
} else { // 如果唔係...
    x = 1; // 就將 x 設做 1。
}

喺組合語言入面,同一段命令望落大致上會係噉樣嘅:

	cmp 	ax, bx  	; 「cmp」係英文「compare」嘅簡寫,呢個命令叫部電腦比較 ax 同 bx。
	jl  	axLess          ; 如果比較結果係 ax 細啲,跳去「axless」嗰命令。
	mov 	word [X], 1     ; 將 x 設做 1,如果 ax 細過 bx,部電腦會跳過呢行命令。
	jmp 	Both            ; 做咗「將 x 設做 1」喇,所以要跳去 Both 嗰度(如果有呢行命令,部電腦就會將 x 設做 -1 再設做 1)。
axLess: 
	mov 	word [X], -1    ; 將 x 設做 -1。
Both:

For 迴圈[編輯]

睇埋:For 迴圈

For 迴圈(For loop)係高級語言實會有嘅一種命令。一個 for 迴圈會指定一個變數,部電腦每行個迴圈一次就會將個變數嘅數值改變,直至個變數嘅數值去到某個位為止。例如係 C 程式語言,就有噉樣嘅句法:

for (int x = 0; x <= 3; x++)
{
    // x 開頭係 0,呢個 for 迴圈每重複一次,x 就會提升 1(x++),而只要 x ≤ 3,呢個迴圈會係噉重複行。
}

以下呢段 8086 嘅組合碼會達到同呢個 for 迴圈一樣嘅效果:

        xor cx,cx   ; cx 暫存器攞嚟做 counter,設佢數值做 0。
loop1   nop         ; 個迴圈嘅內容喺度。
        inc cx      ; 將 cx 暫存器入面嗰個數值升 1。
        cmp cx,3    ; 叫部電腦比較 cx 暫存器嗰個數值同「3」。
        jle loop1   ; 「如果比較結果係兩個數一樣咁大或者 cx 暫存器嗰個數值細啲,返返去 loop1」。

Do-while 迴圈[編輯]

睇埋:Do-while 迴圈

Do-while 迴圈(Do-while loop)係另一種高級語言幾乎實會有嘅一種命令,每個 do-while 迴圈都會包含咗一行或者多行嘅命令,而個迴圈會令到部電腦係噉不停做個迴圈入面嗰啲命令,一路做到某個條件唔再成立為止。例如 C 程式語言就有噉樣嘅句法:

int x = 1;
do {
    // 只要 x = 1,個程式就會係噉重複做 do {} 入面嗰柞命令。
}
while(x == 1)

喺 8086 嘅組合語言當中,呢個 do-while 迴圈係噉嘅:

        mov ax,1    ;  將 ax 暫存器嘅數值設做 1。
loop1   nop         ; 個迴圈嘅內容喺度。
        cmp ax,1    ; 叫部電腦比較 ax 暫存器嗰個數值同「1」。
        je loop1    ; 「如果比較結果係兩個數一樣嘅話,返返去 loop1 嗰行命令度」。

廿一世紀初應用[編輯]

到咗廿一世紀初,無論係專業嘅程式設計員定係得閒玩寫程式嘅人,都係多數偏向鍾意用高級語言,所以「組合語言仲係咪有用」係一個有相當爭議性嘅課題[28]:截至 2017 年 7 月為止,TIOBE 指數嘅評級顯示,如果將主要程式語言按人氣排嘅話,組合語言屬第 11 名-個名次仲高過 Visual Basic [29];事實係,就算係同高級語言比,組合語言都仲係有一啲優勢-例如係有研究一再噉證明咗,雖然相關領域嘅科學家工程師嘗試令到高級語言用嘅編譯器快啲,但好多時將組合語言翻譯做機械碼都仲係快一截[30][31][32];不過事實又係,現代嘅 CPU 快得好交關,所以喺部電腦運行嘅大多數時間,粒 CPU 都係處理閒置嘅狀態,所以「一段源碼能夠以幾快嘅速度翻做電腦識行嘅機械碼」呢家嘢對整體運算速度造成嘅影響理應會愈嚟愈唔明顯[33]

廿一世紀初嘅電腦科學電子工程課程普遍都會教組合語言:雖然專業嘅程式設計員已經好少可會定時定候用組合語言做嘢,但組合語言所教嘅嗰啲概念都仲係好緊要。好似係二進制算術、記憶體嘅管理、堆疊嘅處理同埋編譯器嘅設計等嘅課題實要識少少有關電腦喺硬件層面嘅運作先至會學得明,而一部電腦嘅行為係本質上由佢嘅命令集(instruction set)話事嘅,所以要學電腦點喺硬件層面運作,就要學電腦所屬嘅組合語言(同埋機械語言)。現代電腦一般彼此之間都有相似嘅命令集,所以學一隻組合語言好多時經已夠個學生了解嗮呢啲基本概念[34]

應用例子
  • 電腦系統嘅起動程式(booting program)多數會用組合語言嚟將個系統初始化同埋喺起動個作業系統嗰時測試吓個系統嘅硬件先。例子有同 IBM 相容嘅個人電腦系統同埋 CP/MBIOS
  • 某啲相對低級啲嘅程式語言-好似係 Pascal 或者 C-會俾個用家將組合語言直接噉嵌入去源碼嗰度。呢啲程式好多時仲有能力喺唔同嘅硬件平台嗰度搵返相應嘅組合碼出嚟。
  • 有啲編譯器喺將啲高級語言嘅源碼完全編譯(做機械碼)之前會首先將佢翻做組合碼先,等個用家有得用啲組合碼嚟做除錯或者最佳化。
  • 喺處理能力同 RAM 比較有限嘅個人電腦嗰度,組合語言可以用嚟提高執行程式嘅速度。
  • 組合語言喺還原工程(reverse engineering)上好有用。因為同專利相關嘅問題,好多時啲人都唔鍾意俾第啲人知道佢哋嗰啲程式嘅源碼,就算一間公司肯將佢哋個新軟件嘅源碼俾人知,好多時都淨係會以機械碼嘅形式發放。機械碼要譯做組合碼好易,但係要譯做高級語言就撈絞好多。好似係 IDA Pro 等嘅架生會因為呢個原因而好深入噉使用反組合嘅過程,而黑客等嘅人物會運用呢啲噉嘅架生嚟解開商業軟件嘅源碼-再(例如)將呢啲源碼賣俾出嗰個軟件間公司嘅同行競爭者[35]

註釋[編輯]

  1. 「低級」係指抽象化嘅程度低,所以隻語言會反映部電腦內部嘅運算嘅實況。
  2. 唔同組合語言好多時會用唔同記憶術代表同一個命令。喺 1985 年,電機電子工程師學會(IEEE)出版咗《694 準則》(Standard 694)諗住統一組合器所用嘅記憶術,但電腦科學界一般都唔係好睬佢哋。到咗廿一世紀初,各款組合器都仲係傾向各自用自己嘅記憶術。

睇埋[編輯]

文獻[編輯]

[編輯]

  1. Assembly language. IBM Knowledge Center.
  2. Moore, J. S. (2007). Piton: a mechanically verified assembly-level language (Vol. 3). Springer.
  3. High Level Assembler - Opcodes overview.
  4. Macro instructions. IBM Knowledge Center.
  5. James Saxon; William Plette (1962). Programming the IBM 1401. Prentice-Hall. LCCN 62-20615 – via HathiTrust.
  6. 6.0 6.1 6.2 6.3 6.4 Kahanwal, D. (2013). Abstraction level taxonomy of programming language frameworks. arXiv preprint arXiv:1311.3293.
  7. 7.0 7.1 "Assembly: Review - The Ohio State University" (PDF). 2016.
  8. System calls often vary, e.g. for MVS vs. VSE vs. VM/CMS; the binary/executable formats for different operating systems may also vary. "How do assembly languages depend on operating systems?".
  9. Tech Target - machine code (machine language).
  10. Hennessy, John L.; Patterson, David A. Computer Organization and Design. The Hardware/Software Interface. Morgan Kaufmann Publishers.
  11. Intel Architecture Software Developer's Manual, Volume 2: Instruction Set Reference. Intel Corporation. 1999.
  12. 12.0 12.1 Intel Architecture Software Developer's Manual, Volume 2: Instruction Set Reference. Intel Corporation. 1999. pp. 442 and 35.
  13. Evans, David (2006). "x86 Assembly Guide". University of Virginia.
  14. Moskovitch, R., Feher, C., Tzachar, N., Berger, E., Gitelman, M., Dolev, S., & Elovici, Y. (2008, December). Unknown malcode detection using opcode representation. In European conference on intelligence and security informatics (pp. 204-215). Springer, Berlin, Heidelberg.
  15. Runwal, N., Low, R. M., & Stamp, M. (2012). Opcode graph similarity and metamorphic detection. Journal in computer virology, 8(1-2), 37-52.
  16. IEEE 694-1985 - IEEE Standard for Microprocessor Assembly Language. IEEE Standards Association.
  17. Z80 Op Codes for ZINT. Z80.de.
  18. Extended instruction mnemonics. IBM Knowledge Center.
  19. "The SPARC Architecture Manual, Version 8" (PDF). SPARC, International. 1992.
  20. 20.0 20.1 20.2 20.3 20.4 20.5 David Salomon (1993). Assemblers and Loaders.
  21. Microsoft Corporation. "MASM: Directives & Pseudo-Opcodes" (PDF).
  22. Chapter 8 - Pseudo Op-Codes.
  23. 23.0 23.1 Beck, Leland L. (1996). "2". System Software: An Introduction to Systems Programming. Addison Wesley.
  24. Hyde, Randall. "Chapter 12 – Classes and Objects". The Art of Assembly Language, 2nd Edition. No Starch Press. © 2010.
  25. B. Schwarz, S. Debray, and G. Andrews, "Disassembly of Executable Code Revisited", Proc. of 9th Working Conference on Reverse Engineering (WCRE), pp. 45–54, 2002.
  26. Difference between assembly language and high level language. IT Release.
  27. Decision-Making in Assembly Language. UMBC.
  28. Randall Hyde. "The Great Debate".
  29. "TIOBE Index". TIOBE Software.
  30. "Writing the Fastest Code, by Hand, for Fun: A Human Computer Keeps Speeding Up Chips". New York Times, John Markoff.
  31. "Bit-field-badness". Hardwarebug.org.
  32. "GCC makes a mess". HardwareBug.org.
  33. Click, Cliff. "A Crash Course in Modern Hardware".
  34. Hyde, Randall (1996-09-30). "Foreword ("Why would anyone learn this stuff?"), op. cit.".
  35. A Crash Course in x86 Assembly for Reverse Engineers (PDF).

[編輯]