Ch 00 組合語言準備工作

自從個人電腦走進一般大眾的生活之後,相信有許多人的工作、娛樂已經離不開電腦。在電腦上有著各式各樣的軟體供人們使用,不管是聽音樂、看電影、做統計、寫公文、寫作業、玩遊戲……等等,都能夠滿足人們的需求。但是,具有好奇心的人們,你可知道這些軟體是怎麼來的呢?

原來這些軟體都是經由程式設計師用各種程式語言所撰寫的。對於不了解程式設計的人來說好像很難解釋得清楚什麼是「程式」。此處,小木偶僅舉幾個例子說明。所謂程式,就像你在「開始」堙A選擇「Microsoft Word」,電腦就會執行「Word」,可以讓你做文書處理;如果你選擇「CD 播放程式」,那麼你就可以聽到由光碟機所放出來的音樂,「Word」、「CD 播放程式」都是一種程式,而你在「Word」堜瓵擗J的文章,光碟片上的音樂都是一種資料,我們可以說程式是處理資料的方法,程式設計就是人們依照資料要如何處理,一步一步的把處理的過程依一定的規則寫進電腦,而後電腦就會按照我們原先規劃好的步驟處理資料。您可以參考維基百科有關電腦程式的定義。

一般來說,像「Microsoft Word」這種程式很大,無法用單一程式完成所有功能,所以一般稱為「套裝軟體」或稱「軟體」,而有些程式則很小,就不稱為軟體 ( 其實你稱為軟體也無妨 )。在電腦中要製作程式,一般都是用「程式語言」來撰寫程式,常見的電腦程式語言有「C/C++」、「BASIC」、「PASCAL」等等,每一種語言都有自己的規則,設計方式。小木偶的這個網站主要內容便是「組合語言程式設計」,意思就是用組合語言去設計電腦程式。雖然現在組合語言已經算是式微的語言 ( 很少人學的語言 ),但是小木偶最鍾情的程式語言還是組合語言,因為你卻可以「看見」一條一條的指令如何將資料一步一步的處理,你可以想像資料如何在電腦堙u流動」,電腦的 CPU 如何去處理它,而後會發生什麼樣的變動。

在電腦堙A處理資料的過程大部分發生在幾個重要的晶片上,其中又以中央處理機 ( CPU,central process unit ) 最為重要。處理資料的過程,不外乎是使 CPU 對資料做加、減、乘、除、比較、跳躍……等運算,這種能讓 CPU 運算的方法就叫「指令集」( instruction set )。不同種類的 CPU,其指令集也不一樣,而組合語言的設計方式便和 CPU 的種類有關。 不同,所以撰寫組合語言時所用的規則也不同。以術語來說,就是「CPU 的種類不同,指令集也不同,組合語言語法也不同」。現在的個人電腦,大部分是以英特爾 ( Intel ) 公司所生產的 8086/8088 CPU 為架構的相容機種,而小木偶也只曾學過 8086/8088 CPU 的組合語言,所以這個網站內容便是介紹 8086/8088 組合語言程式設計。


CPU、MS-DOS 與 IBM PC/XT/AT 相容電腦簡史

中國有句古話,飲水思源。既然想以能深入電腦世界的組合語言撰寫程式,那麼先由 CPU、電腦以及 MS-DOS 的發展歷史切入,可能是粗淺了解電腦世界的好方法。底下小木偶將簡單介紹這些 CPU、軟體、電腦公司所發表的重要產品及其特色。

8 位元的 CPU 與 Apple ][

民國 57 年,也就是西元 1968 年,Gordon Moore ( 著名的摩爾定律提出人 )、Andy S. Grove 以及 Bobert Noyce ( 積體電路,integrated circuit,的發明人之一 ) 等人成立英特爾 ( Intel ) 公司,專門生產積體電路,並於 1971 年發展出 4004 晶片,這個晶片是四位元的中央處理器 ( CPU,central process unit ),內含兩千三百個電晶體,工作時脈為 740KHz。4 位元的 CPU 效能自然不足,英特爾繼續努力,於 1974 年先後推出 8008 及其強化版本 8080 兩種 8 位元的處理器。

西元 1975 年,摩托羅拉 ( Motorola ) 公司也開發出 8 位元的 6800,旗下部份離開的工程師所創立的 MOS Technology 公司也開發出 8 位元的 6502 處理機。Steve Jobs 和 Steve Woznick 兄弟在自家車庫中以 6502 晶片研發出紅極一時的 Apple ][,也就是蘋果二號電腦。Apple ][ 有 16KB 記憶體 ( 注意!不是 16MB ),最多可擴充至 64KB,儲存裝置可以用錄音帶或軟碟機。日商任天堂 ( Nintendo ) 公司也以 6502 發展出電視遊樂器。

8086/8088、IBM PC/XT 與 MS-DOS 1.0/2.0

英特爾知道 8 位元的處理器競爭激烈,要在市場打下一片天,唯有提升處理器的性能,於是決定開發 16 位元的處理器,終於於 1978 年推出 8086 CPU,這顆 CPU 由四萬個電晶體組成,在資料傳遞與處理上都是 16 位元,工作時脈為 4.77MHz ( 註一 ),有 20 條位址線,可定址 220 個位址,即 1MB,每個位址表示一個位元組 ( byte ),所以可存取 1MB 位元組。但當時的周邊設備,幾乎都只能接收八位元的資料,所以英特爾另外於 1979 年推出 8088,使其對外的資料傳遞為八位元,內部運算還是 16 位元。雖然這樣子做會使 8088 的性能較 8086 稍差,但是能搭配市場上原有的八位元的周邊裝置,降低成本。

在此同時,專門做大型電腦的 IBM 公司認為個人電腦有很大的商機,於是開始考慮製造個人電腦。為了能迅速的切入市場,IBM 並沒有採取他在大型電腦上的一貫策略,以往 IBM 所生產的大型電腦不論是 CPU 或作業系統統都由自己一手包括,但在個人電腦上反而採取開放系統。民國 70 年 ( 西元 1981 年 ),IBM 發表了自己的個人電腦,稱為「IBM PC」( PC 是個人電腦,personal computer 的縮寫,但是因為這款電腦太成功了,全球各地的個人電腦幾乎都是 IBM 所出產的或與之相容的,所以 PC 本來是 IBM 產品的一個型號,現在卻變成一種商品名稱 ),IBM 採用英特爾出產的 8088 為 CPU,微軟出產的 MS-DOS 為作業系統。IBM 不僅僅開放 IBM PC 所有的技術資料,還提供 BIOS 程式列表,所以有心想製造和 IBM PC 相容的廠商很容易就能生產。因為 IBM 採取這種策略,以及 8088 優異的處理能力,使得 IBM 一舉攻佔 Apple ][ 的市場,日後 PC 以及其相容機種蓬勃發展,而 PC 也不再僅僅是 IBM 的產品名稱,也成為個人電腦的代名詞,而英特爾及微軟也靠著本身的努力及策略成為世界級的大廠商,分別坐上 CPU 及軟體的第一把交椅。以現在的眼光來看,8086/8088 與動輒上 2.0GHz 的時脈、能處理近 4GB 記憶體的 Pentium 4/Athlon XP CPU 相比, 可說是非常差,但是在當卻是一顆無與倫比的 CPU,也從此開啟了微軟與英特爾王朝 ( Wintel )。

言歸正傳,那時候的 IBM PC 配有兩部五又四分之一英吋 360 KB 軟碟機、一部單色或 CGA 顯示卡,記憶體為 64KB,可擴充到 256KB。與之搭配的作業系統是 DOS 1.0,這版的 DOS 並沒有子目錄的觀念,也不能處理硬碟。IBM PC 在開機時,會由 BIOS 先自我檢查硬體有沒有故障,如果無誤,BIOS 再檢查軟碟機 A:,如果在軟碟機 A: 堣w經放入 DOS 開機磁片,那麼就會進入 DOS;如果沒放開機磁片,就會直接進入 BASIC 程式堙A這個 BASIC 是被燒錄在 ROM ( read only memory,唯讀記憶體,這種記憶體在製造過程已把資料、程式碼寫死,故僅可讀出而無法更改的記憶體內容,其內容在關機後也不會消失 ) 晶片堙CIBM PC 的 ROM 分兩部份:8K 的 BIOS 及 32K 的 BASIC 解譯程式。BIOS 是 Basic Input/Output System 的縮寫,它是一段燒錄在 ROM 晶片的程式,此程式負責在開機時自我檢查、規劃其他晶片、控制周邊設備之用,是很重要的程式。

西元 1980 年,Motorola 公司再度開發成功 68000 CPU,這是一顆內部以 32 位元運算,對外以 16 位元傳遞資料的處理器,運作時脈為 8MHz,含有六萬八千個電晶體,在 1984 年被 Apple 公司選為第一代麥金塔電腦 ( Macintosh ) 的 CPU,當時的麥金塔電腦配備滑鼠,其作業系統稱為 Mac OS 就已經是圖形界面,使用者只要用滑鼠點選就能操作電腦,例如把軟碟片的圖示拖到垃圾桶中,軟碟片就會自軟碟機退出,這點比當時的 IBM PC 進步很多。小木偶有幸用過麥金塔一段短時間,令我欽佩不已。可惜麥金塔電腦的價錢太貴,並且 Apple 採取封閉架構無法大量製造,以致於始終為「小眾市場」,但是由於其性能及操作界面始終優於 IBM PC 及其相容機種,故始終能維持不墜於地的局面。

到了西元 1983 年,IBM 發表 IBM PC/XT ( 其命名取自 extended technology ) 電腦,配備一部 10MB 硬碟機及一部五又四分之一英吋 360 KB 軟碟機,為了配合新機器,DOS 也大幅更動並吸收 UNIX 的優點,升級為 DOS 2.0 版,此版本的 DOS 加入了對 10MB 硬碟分割的支援,對管線的操作,樹狀檔案系統的處理,子目錄的管理等新觀念。

80286、IBM PC/AT 與 MS-DOS 3.0

西元 1982 年,英特爾推出 80286 CPU,這顆 CPU 內含十二萬五千個電晶體,工作時脈可以由 6MHz 到 25 MHz,具有 24 條地址線,所以可定址 16MB。它除了是一顆完全的 16 位元 CPU 之外,還有兩個特點,一是保護模式,二是向下相容。80286 有兩種不同的工作模式,真實模式及保護模式。80286 在真實模式中工作時,它就是一顆快速的 8086,原來在 8086 執行的程式,不需要修改就能正確執行,並且更快速。英特爾在既有的 8086 上面多加了指令與功能,並且改進製造技術,使得 80286 可以正確並快速執行原來 8086 的程式,這就是向下相容。當然這也是因為有太多人使用 8086/8088,以致使英特爾不敢放棄既有的顧客。爾後,英特爾所有的 CPU 發展,都依此慣例。

如果 80286 切換到保護模式,應用程式就不能任意存取所有記憶體,換句話說,程式無法存取系統資料,也無法存取另一個程式的資料,可以達到保護目的。不過 80286 的保護模式不成熟,除了重新開機外,無法切換回真實模式,再加上那時候的記憶體相當貴,以致於及大多數電腦及軟體仍在真實模式下工作,使得配有 80286 的電腦被當作快速的 8088 使用,這種情形一直到西元 1995 年,微軟推出 Windows 95 之後才有所改變。作業系統發展的太慢,跟不上 CPU 的發展,甚至早在兩年前,32 位元的 Pentium 早已發表,而作業系統仍在使用 16 位元的 DOS。

西元 1984 年,IBM 所發表 IBM PC/AT ( advanced technology ) 級個人電腦即採用 80286 CPU,PC/AT 機種還裝了五又四分之一英吋 1.2MB 軟碟機及一部 20MB 硬碟機,DOS 也升級到 3.0 版,支援新加入的五又四分之一英吋 1.2MB 軟碟機。

80386、IBM PS/2 與 MS-DOS 3.1、3.2、3.3、4.0

到了這時候,市面上個人電腦需求大增,IBM 與 Intel 為了確保貨源穩定,先後與美商超微 ( AMD )、德國西門子 ( Simens )、Harris 等公司訂約,讓這些公司也能生產 80286 相容的 CPU。不過到了後來,超微的 Am286 CPU 比英特爾的 80286 時脈更快、更便宜、更省電。看在 CPU 龍頭老大英特爾的心堙A當然不是滋味,為了擺脫競爭對手,英特爾開發更先進的 CPU。西元 1985 年10月,推出了 32 位元架構的 80386,這顆 CPU 內含二十七萬五千個電晶體,工作時脈從 16MHz∼40MHz,具有 32 條位址線,所以有 4GB 的定址能力。80386 也有兩種版本,對外資料傳遞或內部運算皆為 32 位元的稱為 80386DX,對外資料傳遞微 16 位元而內部運算為 32 位元的稱為 80386SX,這種情形與 8086 和 8088 相同。80386 相對於 80286 的進步,比 80286 相對於 8086 的進步,可說是有過之無不及,它在設計之初即考慮了多工的需求,所以具有真實模式、保護模式、虛擬 86 模式 ( V86 模式 ) 三種模式,所謂虛擬 86 模式就是在多工的情形下,模擬 8086 CPU,這時在 CPU 空閒時還可執行其他工作。

西元 1986 年,康百特公司 ( Compaq )率先推出以 80386 為 CPU 的 Deskpro 386 個人電腦,翌年,也就是英特爾推出 80386 之後的兩年,IBM 才推出了以 80386 為 CPU 的個人電腦,搭配 MS-DOS 3.30 版,稱為 IBM PS/2 ( personal system 2,亦即第二代個人電腦,PS/2 共有四型,其中三種採用 80386 為 CPU,另一型採用 80286 CPU )。

這時 CPU 運算速度已經非常快了,但是連接周邊設的擴充界面卡,如顯示卡、硬碟控制卡,的速度不能配合,那麼擴充界面卡常常會變成拖累效能的絆腳石。所以擴充界面卡得有所突破了,原先的擴充界面是 IBM PC/XT 所用的 ISA 界面,它是 8 位元,顯然變成 16 位元的擴充界面勢在必行。

IBM PS/2 的擴充界面採用微通道界面,和原來的 PC/XT/AT 的擴充界面不相容,於是使得很多使用者與廠商觀望不前,導致 PS/2 銷售不佳,很快就被市場淘汰,如今只剩鍵盤與滑鼠還有部份使用 PS/2 界面。西元 1988 年,Compaq 公司推出 EISA ( Extended Industry Standard Architecture ) 界面,延續和 ISA 界面相容,許多廠商各自推出內含 EISA 擴充界面且與 IBM PC/AT 相容的機種,因為這些機種成本較小,故銷售額扶搖直上,此後 IBM 再也無力影響個人電腦的新規格,各種規格的製定變成由許多大廠商主導。

由於 286 的慘痛經驗,英特爾決定不把 80386 的技術授權給任何廠商。於是英特爾 80386 獨門生意做了數年,而 AMD 看著 80386 的熱賣卻無法分到一杯羹,著實眼紅,但沒有得到授權,只好自行研發。AMD 以逆向工程解剖 80386,研究其內部線路結構,終於在五年後,也就是西元 1990 年發表 Am386DX 與 Am386SX,此舉當然引起英特爾不滿,於是英特爾控告 AMD 仿造官司。這場官司在西元 1991 年宣判:法官認為晶片的編號不能申請註冊商標,所以 AMD 沒有侵權。這個判決影響後來英特爾發表 80586 時,改以 Pentium 取代。有關英特爾與 AMD 的官司,請看

隨著硬體的更新進步,DOS 也隨之發展。在西元 1984、1986、1987 年,微軟分別發表了 DOS-3.10、3.20、3.30 三個版本。DOS-3.10 新增的功能是在 CONFIG.SYS 中可加入 FCB 敘述,以支援區域網路。DOS-3.20 再新增對三又二分之一英吋軟碟機,也就是 720KB 軟碟機的支援。DOS-3.30 則再加入對 PS/2 界面、三又二分之一英吋軟碟機,也就是 1.44MB 軟碟機以及 32MB 硬碟的支援。到現在這款 1.44MB 軟碟機還是屢見不鮮。

西元 1988 年 8 月份,微軟發表 MS-DOS 4.0,主要的新功能是管理 2GB 硬碟,並新增一個 DOS SHELL 程式,這個程式可以利用選單操作電腦。另外還有一個嘗試,那就是支援擴充記憶體 ( Expanded Memory Specification,EMS )。長久以來,DOS 只能利用 CPU 的真實模式之下執行,在這種模式之下,只能定址 1MB,再扣除視訊記憶體、各種 ROM 所佔據的記憶體,實際上 DOS 所能用的記憶體只有 640KB,也就是所謂的傳統記憶體 ( conventional memory )。DOS 4.0 則利用 EMS 4.0 規格,可以使用 1MB 以上的記憶體作為存放資料之用。但是 DOS 4.0 的錯誤 ( bug ) 太多,以致當時很少人使用,大多數人仍然使用 DOS 3.30。於是同年的 11 月,微軟立即修正這些錯誤,發行 MS-DOS 4.01,但是銷售成績仍然不佳。

80486 與 MS-DOS 5.0

英特爾見到其競爭者,主要對手是超微,已有能力生產 80386 相容 CPU,為了打擊對手,英特爾把握人們追求更好產品的心理,於西元 1989 年 4 月推出具有一百二十萬顆電晶體,時脈 25 MHz 的 80486DX CPU,打算一舉吃掉競爭者的市場,後來陸續把時脈推進到 33MHz、50MHz。80486DX 也是一顆 32 位元的 CPU,與 80386 比較,除了較高時脈外,還在 CPU 內建了 8K 位元組的快取 ( cache ) 記憶體與浮點處理器。所謂快取是為了彌補 CPU 與記憶體速度上的差距。CPU 運算速度遠高於記憶體傳輸速度,所以 CPU 運算完畢後,常常在等待記憶體把資料傳過來以便下一次運算,在 CPU 較慢的年代堙A這一點等待還不致影響太大,但如果 CPU 運算速度快,而記憶體無法跟上,整體效能就會被影響。所以為了縮短等待的時間,把一部份的內容儲存在與 CPU 一樣速度的快取記憶體中,當 CPU 需要資料時就在快取記憶體中尋找,假如沒有再去記憶體中尋找,這樣就能增加效能。一般而言,CPU 運算的結果與所需的資料,大約都是集中在幾 K 位元組的範圍內,所以這個快取大小不需要和記憶體一樣大,否則成本將大幅增加。英特爾也發行另一種版本的 80486,即 80486 SX。DX 與 SX 的差別是 DX 含有浮點運算器而 SX 則是不含浮點運算器。

之後英特爾又發展出倍頻技術。因為 80486 運算速度較記憶體、匯流排速度快得多,為了不被電腦內部的這些慢速元件影響,於是讓這些較慢速的元件以 33MHz 時脈運作,而 80486 則是以兩倍速或三倍速的時脈運作,分別稱之為 DX2 與 DX4,因此 488DX2-50、486DX2-66、486DX4-100 紛紛出籠了。

從技術的角度來看,80486 與 80386 相去不遠,僅加上快取記憶體與浮點運算器,所以超微與 Cyrix 很快就能推出 80486 等級的 CPU,Am486DX 與 Cx486DX,到了後期,超微加強倍頻技術及加大快取,使其速度可達 160MHz ( 超頻到 40MHz 時脈,倍頻用 4 倍 ),其效能甚至可與英特爾的 Pentium 75 一較長短,所以超微稱這顆 CPU 為 Am5x86- P75。

西元 1991 年六月份,微軟再度發表新版的 MS-DOS 5.0,這版 DOS 最大的進步是在記憶體的管理,讓可用的傳統記憶體變多了。由於使用上層記憶體 ( Upper Memory Block,UMB ) 與 HMA ( 指延伸記憶體的最低約 64KB 的記憶體 )。由於這兩塊記憶體的使用,可以把 DOS 核心、驅動程式以及常駐程式放在 640KB 到 1088KB 的記憶體空隙中,大大增加了應用程式可以使用的傳統記憶體空間。除此之外,還附贈 QuickBasic 程式開發工具可供撰寫 BASIC 程式。MS-DOS 5.0 也改善了純文字檔的編輯器,原來難用的行編輯器,EDLIN,變成好用的全螢幕編輯器,EDIT 了。

Pentium、Pentium Pro、Pentium II 與 K5、K6、K6-2

英特爾為擺脫競爭者,再度於西元 1993 年,推出 80586,但因為註冊商標的法律問題而改名 Pentium,中文稱為「奔騰」。最先推出的是 Pentium 60/66,分別是以時脈 60、66MHz 運作,其核心稱為 P5,含有三百一十萬個電晶體,及 8KB 的指令快取與 8KB 的資料快取。Pentium 也是一顆 32 位元的 CPU,但是其對外匯流排是 64 位元的,這並不表示 Pentium 可以執行 64 位元應用程式,因其暫存器仍然是 32 位元寬度,所以仍算是 32 位元的處理機。它與 80486 最大的改進是超純量架構,亦即有兩條管線,U 管線 ( 可以同時處理任何指令 ) 與 V 管線 ( 可以處理簡單的指令 ) 因此每個時脈能處理的指令大約是 486 的兩倍。可惜這兩款 Pentium 有過熱及浮點運算有錯誤的問題 ( Pentium FDIV bug ),以致讓英特爾很快的改良 P5 核心,而推出以 P54C 為核心的 Pentium 75/90/100/120/133/150/166/200/233 MHz。

以 P54C 核心的 Pentium 是一顆叫好又叫座的 CPU,英特爾於西元 1996 年底更在 Pentium 的基礎上加入為了多媒體運算而命名的 Pentium MMX,其核心稱為 P55C。Pentium MMX 的快取記憶體增為 32KB,電晶體數為四百五十萬個,而最重要的改進是新增了 57 個多媒體指令集,所謂的 MMX 指的是 Mathematic Matrix Extension,這 57 個指令是用來處理數學陣列運算,並採用一條指令可處理多筆資料 ( 即所謂的 SIMD,single instruction,multiple data ),這種處理方式很適合用來處理聲音、影像等資料,故又有人稱為 MultiMedia eXtension。Pentium MMX 共有三種時脈,166、200、233MHz。

在發表 Pentium MMX 不久之前的西元 1995 年 11 月,英特爾發表另一顆以 P6 核心的 CPU,Pentium Pro。Pentium Pro 內含五百五十萬個電晶體的運算核心與一千五百五十萬個電晶體的第二階快取記憶體,它也是一顆 32 位元的 CPU,工作時脈為 150、166、180、200MHz。Pentium Pro 的最大特色在於首先採用雙晶粒封裝與內建全速第二層快取,雙晶粒自然是指將運算核心與第二階快取記憶體兩顆晶片一同裝入 CPU 中,中間並以高頻寬的匯流排連接,因此第二階層快取能全速運行,Pentium Pro 的第二階層快取記憶體有三種版本:256KB、512KB、1MB。由技術上來看,Pentium Pro 的確是一顆相當優秀的 CPU,但是由市場的觀點來看,卻是失敗的作品,因為雙晶粒封裝造成良率很低故價錢始終無法壓低,再加上當時 32 位元作業系統與應用程式尚不普遍,而 Pentium Pro 執行 16 位元的程式速度太慢,以致市場始終接受度不高。這給了 AMD 在 K5 失敗後的喘息機會。於是英特爾改弦易轍,推出 Pentium II 取代 Pentium Pro,而讓 Pentium Pro 進軍伺服器的 CPU 市場。

AMD 雖想緊追不捨,但是因逆向工程曠日費時,對電路複雜的 Pentium 恐怕得花費更多時間,所以 AMD 改採自行設計全新架構的 CPU,稱為 K5,但接腳與 Pentium 完全相容。AMD 在 K5 中加入一層複雜指令集 ( CISC ) 轉換成精簡指令集 ( RISC ) 的 RISC86,以期能利用精簡指令集的優點而使 K5 的運算速度大幅提升。西元 1995 年,AMD 發表了 K5-PR75/90/100/120/133,K5 含有四百二十萬個電晶體,24KB 快取記憶體 ( 16KB 的資料快取與 8KB 的指令快取 )。雖然 AMD 計畫中的 K5 架構看起來不錯,但是理想與現實總是有差距的,K5 的效能表現得不如預期得好,因此 K5 銷售不佳,使 AMD 接連虧損數年面臨經營困境。就在此時,AMD 買下另一家也是研發 CPU 的廠商,NexGen。

NexGen 成立於 1986 年,專門設計並出產 CPU。他的第一個產品是開發出與 80386 等級相同的 CPU,第二個產品是 Nx586 CPU,於西元 1994 年推出,並嘗試與 Intel 的 Pentium 直接抗衡,這也是第一顆向 Pentium 發出挑戰的處理器,但是 NexGen 的接腳與 Pentium 不相容。AMD 於西元 1996 年併購 NexGen 時,也同時延聘了該公司的 CPU 設計團隊,並延續 Nx586 的設計來開發新的 CPU,K6 處理器。K6 於西元 1997 年四月正式發表,它有八百八十萬個電晶體,也是一顆 32 位元的 CPU,K6 的工作時脈有 166、200、233MHz 三種。K6 的效能除了浮點運算外,其餘都不比 Pentium 差,且較便宜,再加上西元 1997 年底左右,世界經濟不景氣,K6 搭著低價電腦的順風車,著實讓 AMD 扳回了顏面。

英特爾為了讓 AMD 等競爭廠商退出,於 1997 年 5 月推出新的 CPU,稱為 Pentium II。它是基於 Pentium Pro 的 P6 核心架構,但加強了 16 位元的效能,以及加入 MMX 指令集。Pentium II 有七百五十萬顆電晶體,是一顆 32 位元的 CPU,對外匯流排為 64 位元,第一階快取為 32KB。Pentium II 和 Pentium Pro 相同,也有第二階快取記憶體,512KB,但為了提升良率,Pentium II 不用 CPU 插座,而把運算核心、第二階快取記憶體封裝於一個卡匣內,用像界面卡的方式插在主機板上,稱為 Slot 1。英特爾還申請 Slot 1 的專利權,到此不僅 CPU 名稱是一種商標,連 CPU 的插槽也變成獨家生產了,這些重重關卡當然是為了阻礙競爭者,卻同時也提高自己組裝電腦的門檻。Pentium II 有兩種核心,早期稱為 Klamath,350 奈米製程,工作有 233/266 MHz 兩種速度。中期改以 250 奈米製程的 Deschutes 核心,工作時脈有 266/330/350/400/450 MHz。

雖然英特爾改善了生產良率,但因經濟不景氣,一般民眾不太願意花大錢買較貴的 Pentium II,反而願意買執行效率不輸給 Pentium II 而且價錢便宜的 K6-2。K6-2 是 AMD 在西元 1998 年五月發表的一顆 CPU,含九百三十萬個電晶體,64KB 的第一階快取記憶體,採用 250 奈米製程,工作時脈有 266/300/333/350/366/380/400/450/475/500/533/550 MHz。

西元 1993 年四月,微軟發表新的 DOS,MS-DOS 6.00。最大的改變是新增了磁碟壓縮程式與多重開機。磁碟壓縮程式,DOUBLE SPACE,它可在資料儲存於硬碟前,先壓縮,這個作業在背景完成,使用者完全感覺不出來。多重開機可以讓使用者在開機時選擇所要進入的 DOS 環境,這是為了適應更多元的使用者。除此之外,MS-DOS 6.00 還新增了 CentralPoint 公司的抗病毒軟體 CPAV,可以掃描病毒與清除病毒。西元 1994 年,微軟再推出 MS-DOS 6.20,這一版本主要強化了磁碟壓縮程式與多重開機。在西元 1994 年五月,微軟發表最後一版 DOS,MS-DOS 6.22。

未完的故事

好了,小木偶想故事就說到這塈a。雖然後來英特爾又發表了 Pentium !!!、Pentium 4,乃至到最新的 64 位元酷睿 ( Core 2 Duo ),AMD 也同樣的先後發表 K6-3、Athlon、Athlon 64 與之抗衡,微軟繼 MS-DOS 6.22 之後雖不再發行 DOS 了,但是 DOS 的子孫,Windows 95/98/98SE/Me,乃至後來的 Windows 2000/XP/Vista/7 也不斷的推陳出新。但我再說下去只怕變成老太婆的裹腳布,又臭又長了,所以這故事雖未結束,但就此打住。

在此得特別感謝 AMD 公司,因為有他們的努力,CPU 市場才不至於像作業系統市場被壟斷,大眾才能享受價美物廉的 CPU。不像作業系統,由微軟一家壟斷,於是大家便不會享有互相競爭所帶來的好處。最後還得感謝網際網路的便利,讓我很快的查到這些舊資料。小木偶大部份是參考維基百科微處理器部份與 The BalusC Server 網站。


撰寫組合語言程式所需硬體設備

想要撰寫 80X86 組合語言程式,所需要的硬體就是一部電腦,而此電腦只要是 80X86 相容的機器都可以,包含 Intel 所出品的 CPU,如 8088/8086/80286/80386/80486/Pentium/Pentium Pro/Pentium II/Pentium !!!/Pentium 4,或是 AMD 所發表的 CPU,如 K5/K6/K6-2/Athlon 等都可以。

至於周邊配備也沒有限制。螢幕不論彩色或單色皆可,也不管陰極射線管 ( CRT )或液晶 ( LCD ) 螢幕都可以,螢幕所接的顯示卡也不管是 PCI、AGP 1X/2X/4X/8X 或最新的 PCI-E 都可以。硬碟所佔用的空間很小,絕不超過 10MB,當然如果您常寫程式的話,所需空間可能會大一點。其他周邊設備,像印表機、數據機、網路卡、音效卡都可有可無。此外我們還會提到 80X87 浮點運算器 ( FPU ),只要你的 CPU 是 80486DX 以上等級的 CPU 都內含了。( 其實現在的配備早就是 Pentium 4 加上彩色螢幕了,所以現在 ( 西元 2001 年 ) 市面上的 IBM 相容機種都合乎撰寫組合語言程式的需求,那我主要的意思是其實撰寫組合語言程式,所需配備很低,市售機種包含自行組裝的都符合組合語言程式撰寫 )

事實上,Apple 機種也是可以寫組合語言,但是 Apple Mac 所使用的 CPU ,680X0 的指令集和 80X86 是不同的,所以指令集、語法都不同,而這個網站將只介紹 80X86 家族 CPU 的組合語言。( 其實小木偶只學過 80X86 組合語言而不會 680X0 指令集 )


撰寫組合語言程式所需軟體

現在 ( 民國 90 年,西元 2001 年 ) 已是 32 位元的作業系統風行的時候了,由於組合言語與硬體、作業系統密不可分,所以用組合語言撰寫 16 位元的 DOS 程式與撰寫 32 位元的 Window 9x/Me/NT/2K/XP 程式是不盡相同的。雖然 16 位元的 DOS 作業系統已逐漸沒落,但是以學習組合語言的觀點來說,它仍然是最好的選擇。底下小木偶著重在說明如何以組合語言撰寫 16 位元的 DOS 程式,假如您想試試以組合語言撰寫 32 位元的 Windows 程式,請參閱「Win32 的組合語言」。但若您從未接觸過組合語言,還是建議您先學學 DOS 底下的組合語言,再來才學 Win32 組合語言。

撰寫組合語言程式需要什麼軟體呢?

  1. 作業系統不管你是 DOS、OS/2、Windows 95/98/98SE/Me/2K/XP 都可以
    雖然剛剛才說,初學者在 16 位元的 DOS 系統學習組合語言較為簡單,但是現在早已是 Windows 9x/Me/NT/2K 等 32 位元的作業系統大行其道的時代了,到了民國 100 年時,甚至 64 位元的作業系統亦逐漸普及,使用 16 位元的 DOS 系統的電腦早已成鳳毛麟角了,那麼還能再安裝 DOS 嗎?當然是能的!甚至還可以不在分割硬碟或重新安裝 Windows 作業系統的情形下安裝好 DOS。方法就是安裝虛擬機器,虛擬機器軟體能在您的電腦埵w裝一部虛擬機器,請參閱附錄十一

  2. 組譯器:組譯器的功用是把原始碼組譯成目的檔 ( 副檔名是 OBJ )。小木偶習慣上喜歡用 Microsoft Macro Assembly 5.0 ( 就是 MASM 5.0 ),當然也可以用 MASM 6.x ( 註二 )。或是用免費且跨平台的 NASM。

  3. 連結器:連結器的功用是把目的檔互相連結成可執行檔,或把目的檔與程式庫連結成可執行檔。小木偶習慣上使用 MASM 5.0 內附的連結器 ( LINK.EXE ),也可以到 Microsoft 的網站下載 LINK 5.63 版
    此處要注意,有許多初學者以為版本越高越好,但是在組合語言的連結器卻不一定如此。16 位元的 DOS 系統與 32 位元的 Win 9x/XP/Vista 系統的可執行檔的副檔名雖然都是 *.EXE,但是格式不同。組譯器產生的目的檔格式也不同,前者格式稱為 OMF,後者稱為 COFF。雖然 MASM 6.x 的組譯器都可以製作出 OMF 或 COFF 格式的目的檔,但是使其連結成可執行檔的 LINK.EXE 卻有兩種。能使 OMF 格式目的檔變成可執行檔的 LINK.EXE 稱為 Segment 連結器,最高版本是 5.63,這是用來製作 DOS 程式的;能使 COFF 格式的目的檔變成可執行檔的 LINK.EXE 稱為 Incremental 連結器,這是用來製作 Windows 程式的。初學者千萬別弄錯了。此外,還有許多初學者會下載 MASM32 工具包,這個是用來製作 Win32 程式的。

  4. 編輯器:可使用任何一個文書處理器如 PE2.EXE、小作家、筆記本、UltraEdit 都可以,但是最後都得存成純文字檔,並且更改副檔名為 *.ASM

  5. 除錯器:DOS 內附的 DEBUG.EXE 是最常用的除錯器,也是一般坊間組合語言書籍常介紹的除錯器。( Windows 95/98/98SE 也內附 DEBUG.EXE 除錯器,位於 C:\WINDOWS\COMMAND 資料夾底下 )。除了 DEBUG 外,微軟出品的 MASM 4.0 中,也附有一個除錯器,稱為符號除錯器,SYMDEB ( Symbol Debug,可在此處下載 )。當然,也可以用功能強大的 CodeView 或是 SoftICE。

  6. 公用程式-EXE2BIN.EXE:這是一個將 *.EXE 可執行檔轉換成 *.BIN 或 *.COM 的程式,不過並非所有的 *.EXE 都可轉換成 *.COM 執行檔。用原版的 DOS 6.x/5.x 磁片安裝好後,即可找到 EXE2BIN.EXE 程式。但 Windows 9x/Me/XP 並沒有附送,如果你在 Windows 9x/Me/XP 執行 DOS 5.x/6.x 的 EXE2BIN.EXE,電腦會跟你說版本不符無法執行,你可以自行修改或由註二的網站取得。

  7. 虛擬機器軟體:現在 PC 上的作業系統 ( Windows、OS/2 或 Linux ) 幾乎以圖形界面方式操作,這些作業系統也都是 32 位元的作業系統,對於組合語言的初學者而言,並不是理想的作業系統;最理想的是 16 位元的 MS-DOS 作業系統,但是如果要在電腦上安裝 MS-DOS,會要大幅更改硬碟 ( 需要重新分割、格式化等等 ),但是虛擬機器軟體可解決這個問題。我們可以在網際網路 ( internet ) 上搜尋「虛擬機器」,這種軟體可以在現有的作業系統上虛擬出一台新的電腦硬體 ( 稱為虛擬機器 ),我們可以在這台虛擬機器上安裝 MS-DOS 作為練習之用。常見的虛擬電腦軟體有微軟的 Virtual PC、VMWare 等等,小木偶慣用的是 Virtual PC 2007,可以到微軟的網站上下載。至於它的用法可以參考附錄十一

安排寫組合語言的環境

若您打算撰寫組合語言程式,還得自行設定環境。

小木偶的使用環境:用 MASM 5.0

假如你用 MASM 5.0,最簡單的方式就是將 MASM.EXE、LINK.EXE、DEBUG.EXE、EXE2BIN.EXE 都拷貝在同一目錄即可,原始碼(就是 *.ASM 檔)也可以放在同一目錄,但這樣做並不是好方法。最好是能把資料 ( 就是原始碼 ) 與軟體 ( 就是 MASM.EXE、LINK.EXE 等程式 ) 能分開儲存在不同硬碟或不同的目錄,以便能定期備份您所撰寫的原始碼,因為這些可是您心血結晶,整個世界只有您自己擁有,若遺失或損壞了可就再也無法挽回,所以要定期備份,而組譯器、除錯器等軟體則在網際網路上幾乎隨找隨到,不必擔心。也因為要備份,所以原始碼和組譯器等軟體分開存放於不同目錄是較好的做法。

小木偶的原始碼是在 E:\HomePage\SOURCE 資料夾內,組合語言組譯器、連結等軟體是在 E:\HomePage\MAMS50 資料夾內,如下:( 黃色字是 DOS 模式下輸入的字最後再按一次 Enter 鍵)

E:\HomePage\MASM50>dir [Enter]

 Volume in drive E is DATA_1
 Volume Serial Number is 0330-08F6
 Directory of E:\HomePage\MASM50

.              <DIR>        01-31-02   3:22 .
..             <DIR>        01-31-02   3:22 ..
MASM     EXE       103,175  07-31-87   0:00 MASM.EXE
LINK     EXE        39,172  07-24-87   0:00 LINK.EXE
EXE2BIN  EXE         6,651  04-09-91   0:00 EXE2BIN.EXE
SYMDEB   EXE        27,459  10-16-85   4:00 SYMDEB.EXE
DEBUG    EXE        20,554  05-05-99  22:22 DEBUG.EXE
         5 file(s)        197,011 bytes
         2 dir(s)        7,984.45 MB free

E:\HomePage\MASM50>

使用 MASM 6.11d

假如您使用註二所提到的方法,由微軟網站上下載 BINS_DDK.EXE 、98SETUP.EXE 而取得 MASM 6.11d 的話,您可以只把其中的 ML.EXE、ML.ERR、EXE2BIN.EXE 拷貝到任何一個新開設的目錄作為練習用,例如「E:\HomePage\MASM611D」(當然目錄名可隨自己高興任意取名),然後再由上述微軟網站下載 LINK 5.63,並且將它解壓縮於同一目錄。再於 E:\HomePage 目錄下另開設一個子目錄「SOURCE」(也可任意命名),作為存放自己設計的原始程式之用。

小木偶使用的編輯器:UltraEdit32

凡是可以把檔案存成 *.TXT 的文書編輯器都可作為編輯器,像 Word、NotePad 等等,不過組合語言原始碼的副檔名是 *.ASM,所以在您撰寫好原始程式後,得存成 *.ASM 檔。*.ASM 檔其實也是個純文字檔,和 *.TXT 一樣。

以前在 DOS 時代,小木偶用 PE2,而現在在 Windows 時代,則用 UltraEdit32 7.20 版,因為 UltraEdit32 歷史悠久,小木偶習慣了他的使用方式,故一直使用他。( 現在小木偶撰寫組合語言時,大多在 UltraEdit32 中編寫好後,在 Win98 SE 的 DOS 模式組譯、連結並執行,即使是寫 DOS 程式亦是如此。)

UltraEdit32 很容易就可在網際網路上下載得到。此處小木偶要說的是,如何設定使 UltraEdit32 更適合編輯組合語言原始檔。下圖是小木偶的 UltraEdit32 編輯組合語言程式碼畫面:

以 UltraEdit32 編輯組合語言原始碼畫面

您應當可發現,指令集、暫存器、變數等顏色均不同,您也可以用底下的步驟使 UltraEdit32 能顯示高亮度語法。

  1. 首先把下面的文字加在你安裝 UltraEdit32 子目錄內的一個名為 WORDFILE.TXT 的最後面,這段文字您也可以視需要加以修改。

    /L6"組合語言" MASM_LANG Nocase Line Comment = ; File Extensions = ASM COD INB INC MAC
    /Delimiters = ~!%&^*()-+=|\/{}[]:;"'<> ,
    /Function String = "%[a-zA-Z0-9_@?$]+[ ^t]+proc+[ ^t^p]"
    /C1"80x86/x87指令集"
    AAA AAD AAM AAS ADC ADD AND ARPL
    BOUND BSF BSR BSWAP BT BTC BTR BTS
    CALL CBW CDQ CLC CLD CLI CLTS CMC CMOV CMP CMPS CMPSB CMPSD CMPSW CMPXCHG
    CMPXCHG8B CPUID CWD CWDE
    DAA DAS DEC DIV
    ENTER ESC
    F2XM1 FABS FADD FADDP FBLD FBSTP FCHS FCLEX FCMOV FCOM FCOMP FCOMPP FCOS
    FDECSTP FDIV FDIVP FDIVR FDIVRP FFREE FIADD FICOM FICOMP FIDIV FIDIVR FILD
    FIMUL FINCSTP FINIT FIST FISTP FISUB FISUBR FLD FLD1 FLDCW FLDENV FLDL2E
    FLDL2T FLDLG2 FLDLN2 FLDPI FLDZ FLY2X FLY2XP1 FMUL FMULP FNCLEX FNINIT FNOP
    FNSAVE FNSTCW FNSTENV FNSTSW FPATAN FPREM FPREM1 FPTAN FQRT FRNDINT FRSTOR
    FSAVE FSCALE FSIN FSINCOS FST FSTCW FSTENV FSTP FSTSW FSUB FSUBP FSUBR
    FSUBRB FTST FUCOM FUCOMP FUCOMPP FWAIT FXAM FXCH FXTRACT
    HLT
    IDIV IMUL IN INC INS INSB INSD INSW INT INTO INVD INVLPG IRET IRETD
    JA JAE JB JBE JC JCXZ JE JECXZ JG JGE JL JLE JMP JNA JNAE JNB JNBE JNC JNE
    JNG JNGE JNL JNLE JNO JNP JNS JNZ JO JP JPE JPO JS JZ
    LAHF LAR LDS LEA LEAVE LES LFS LGDT LGS LIDT LLDT LMSW LOCK LODS LODSB
    LODSD LODSW LOOP LOOPE LOOPNE LOOPNZ LOOPZ LSL LSS LTR
    MOV MOVS MOVSB MOVSD MOVSW MOVSX MOVZX MUL
    NEG NOP NOT
    OIO OR OUT OUTS OUTSB OUTSD OUTSW
    POP POPA POPAD POPF POPFD PUSH PUSHA PUSHAD PUSHF PUSHFD PUSHW
    RCL RCR RDMSR RDTSC REP REPE REPNE REPNZ REPZ RET RETF RETN ROL ROR RSDC
    RSLDT RSM RSTS
    SAHF SAL SAR SBB SCAS SCASB SCASD SCASW SETA SETAE SETB SETBE SETC SETE
    SETG SETGE SETL SETLE SETNA SETNAE SETNB SETNC SETNE SETNG SETNGE SETNL
    SETNLE SETNO SETNP SETNS SETNZ SETO SETP SETPE SETPO SETS SETZ SGDT SHL
    SHLD SHR SHRD SIDT SLDT SMSW STC STD STI STOS STOSB STOSD STOSW STR SUB
    SVDC SVLDT SVTS
    TEST
    VERR VERW
    WAIT WBINVD WRMSR
    XADD XCHG XLAT XLATB XOR
    /C2"假指令"
    %COND %OUT
    .186 .286 .286C .286P .287 .386 .386P .387 .486 .486C .486P .586 .586P .686
    .686P .8086 .8087 .ALPHA .BREAK .BREAKIF .CODE .CONST .CONTINUE .CREF .DATA .DATA? .DOSSEG
    .ELSE .ELSEIF .ENDIF .ENDW .ERR .ERR1 .ERR2 .ERRB .ERRDEF .ERRDIF .ERRE .EXIT
    .FARDATA .FARDATA?  .IF .K3D .LALL .LFCOND
    .LIST .MMX .MODEL .MSFLOAT .NOLIST .NOLISTMACRO .RADIX .REPEAT
    .STARTUP .SALL .SEQ .SFCOND .STACK .TYPE .UNTIL .UNTILCXZ .WHILE .XALL .XCREF .XLIST
    @CATSTR @CODE @CODESIZE @CPU @CURSEG @DATA @DATA? @DATASIZE @DATE @ENVIRON
    @FARDATA @FARDATA? @FILENAME @INSTR @INTERFACE @MODEL @SIZESTR @STACK
    @STARTUP @SUBSTR @TIME @VERSION @WORDSIZE
    ADDR ALIGN AND ARG ASSUME AT
    BASIC BYTE
    C CASEMAP CATSTR CODEPTR CODESEG COMM COMMENT COMMON COMPACT
    DATAPTR DB DD DF DOSSEG DUP DQ DT DW DWORD
    ECHO ELSE ELSEIF ELSEIFDEF ELSEIFIDN ELSEIFIDNI END ENDIF ENDM ENDP ENDS
    EPILOGUE EPILOGUEDEF EQ EQU EVEN EXITM EXPORT EXPR32 EXTERN EXTERNDEF EXTRN
    FAR FAR16 FAR32 FARSTACK FLAT FOR FORC FORTRAN FWORD
    GE GLOBAL GOTO GROUP GT
    HIGH HIGHWORD HUGE
    IDEAL IF IF1 IF2 IFB IFDEF IFDIF IFDIFI IFIDN IFIDNI IFE IFNB IFNDEF
    INCLUDE INCLUDELIB INSTR INTEGER INVOKE IRP IRPC JUMPS
    LABEL LARGE LE LENGTH LENGTHOF LISTING LOCAL LOCALS LROFFSET LOW LOWWORD LT
    MACRO MASK MASM MASM51 MEDIUM MEMORY MM2WORD MMWORD MODEL MULTERRS
    NAME NEAR NEAR32 NLE NOKEYWORD NOLIST NOLOCALS NOLJMP NOLOCALS NOMASM51
    NONE NONUNIQUE NOSCOPED NOSMART NOT NOTHING
    OFFSET OPATTR OPTION OR ORG
    PAGE PARA PASCAL POPCONTEXT PRIVATE PROC PROLOGUE PROLOGUEDEF PROTO PTR
    PUBLIC PUBLICDLL PURGE PUSHCONTEXT PWORD QUIRKS QWORD
    READONLY REAL4 REAL8 REAL10 RECORD REPT REQ
    SBYTE SDWORD SEG SEGMENT SHL SHORT SIZE SIZEOF SHR SMALL SMART STACK
    STDCALL STRUC STRUCT SUBSTR SUBTITLE SUBTTL SWORD SYMTYPE
    TBYTE TEXTEQU THIS TINY TITLE TWORD TYPE TYPEDEF
    USE16 USE32 USES UNION VARARG WIDTH WORD XOR
    \
    /C3"運算子"
    !
    %
    &
    *
    +
    ,
    -
    // /
    >
    =
    <
    |
    /C4"暫存器"
    $
    ?
    @@ @B @F
    AH AL AX
    BH BL BP BPL BX
    CARRY? CH CL CR0 CR2 CR3 CR4 CS CX
    DH DI DIL DL DR0 DR1 DR2 DR3 DR4 DR5 DR6 DR7 DS DX
    EAX EBP EBX ECX EDI EDX EIP ES ESI ESP EXT0 EXT1 EXT2 EXT3 EXT4 EXT5 EXT6 EXT7
    EXTB0 EXTB1 EXTB2 EXTB3
    FS
    GS
    IP
    MM MM0 MM1 MM2 MM3 MM4 MM5 MM6 MM7 MM8 MM9 MM10 MM11 MM12 MM13 MM14 MM15
    OVERFLOW?
    PARITY?
    R10 R10B R10D R10W R11 R11B R11D R11W R12 R12B R12D R12W R13 R13B R13D R13W
    R14 R14B R14D R14W R15 R15B R15D R15W R8 R8B R8D R8W R9 R9B R9D R9W
    RAX RBP RBX RCX RDI RIP RDX RSI RSP
    SI SIGN? SIL SP SPL SS
    TR3 TR4 TR5 TR6 TR7
    XMM XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 XMM9 XMM10 XMM11 XMM12 XMM13 XMM14 XMM15
    ZERO?
    /C5"MMX 3DNow SIMD"
    ADDPS ADDSS ANDNPS ANDPS
    CMPEQPS CMPEQSS CMPLEPS CMPLESS CMPLTPS CMPLTSS CMPNEQPS CMPNEQSS CMPNLEPS
    CMPNLESS CMPNLTPS CMPNLTSS CMPORDPS CMPORDSS CMPPS CMPSS CMPUNORDPS
    CMPUNORDSS COMISS CVTPI2PS CVTPS2PI CVTSI2SS CVTTPS2PI CVTTSS2SI CVTSS2SI
    DIVPS DIVSS
    EMMS
    FEMMS FXRSTOR FXSAVE
    LDMXCSR
    MASKMOVQ MAXPS MAXSS MINPS MINSS MOVAPS MOVD MOVDF MOVDT MOVHPS MOVHLPS
    MOVLHPS MOVLPS MOVMSKPS MOVNTPS MOVNTQ MOVQ MOVSS MOVUPS MULPS MULSS
    ORPS
    PACKSSDW PACKSSWB PACKUSWB PADDB PADDD PADDSB PADDSW PADDUSB PADDUSW PADDW
    PAND PANDN PAVGB PAVGUSB PAVGW PCMPEQB PCMPEQD PCMPEQD PCMPEQW PCMPGTB
    PCMPGTD PCMPGTW PEXTRW PF2ID PFACC PFADD PFCMPEQ PFCMPGE PFCMPGT PFMAX
    PFMIN PFMUL PFRCP PFRCPIT1 PFRCPIT2 PFSQIT1 PFRSQRT PFSUB PFSUBR PI2FD
    PINSRW PMADDWD PMAXSW PMAXUB PMINSW PMINUB PMOVMSKB PMULHRW PMULHUW PMULHW
    PMULLW POR PREFETCH PREFETCHW PREFETCHNTA PREFETCHT0 PREFETCHT1 PREFETCHT2
    PSADBW PSLLD PSLLQ PSLLW PSRAD PSRAW PSRLD PSRLQ PSRLW PSUBB PSUBD PSUBSB
    PSUBSW PSUBUSB PSUBUSW PSUBW PUNPCKHBW PUNPCKHDQ PUNPCKHWD PUNPCKLBW
    PUNPCKLDQ PUNPCKLWD PXOR PSHUFW
    RCPPS RCPSS RDPMC RSQRTPS RSQRTSS
    SFENCE SHUFPS SQRTPS SQRTSS STMXCSR SUBPS SUBSS SYSCALL SYSRET
    UCOMISS UNPCKHPS UNPCKPS UNPCKLPS
    XMMWORD XORPS

    這段文字是用來指示 UltraEdit32 如何顯示顏色。第一行的「/L6"組合語言"」說明這一段是組合語言的顏色定義 ( L 應該是指 Language 的意思,WORDFILE.TXT 是以「/L」來定義不同的語言,當然「組合語言」這四字可以修改成其他文字,例如大陸上用「彙編」表示組合語言 ),UltraEdit32 已經事先定義了五種語言的顏色,但不包含組合語言,所以我們自行加入組合語言當做第六種,故以「L6」表示。

  2. 啟動 UltraEdit32,在 UltraEdit32 選單「Advanced」→「Configuration」的「Syntax Highlighting」標籤中看到 Language: 複合框中有「C/C++」,如下圖:

    UltraEdit Configuration
    按下「C/C++」複合框右邊的按鈕後,出現許多已定義的語言,假如您已經在 WORDFILE.TXT 之後加上剛剛那段文字,這時就會出現「組合語言」的選項了。
    選擇「組合語言」,然後在 Language 下面的 Color Group 可以選擇顏色,在上述那一大段文字中定義了三種顏色,「/C1"x86 指令"」、「/C2"暫存器"」、「/C3"假指令"」,此外還有 UltraEdit32 預先設定的「Normal Text」、「Numbers」等等,都可以按下 Color Group 後,選擇要修改那一項的顏色,如下圖修改「x86 指令」的顏色,先在 Color Group 選擇它:
    再修改 Color Group 底下的「Color:」與「Background」顏色分別成淡藍色與黑色,再按下「套用」按鈕,這樣只要是 80x86 指令都會在 UltraEdit32 中呈現淡藍色字黑底的模樣。
  3. 其他項目的顏色也依上面方式修改即可呈現如小木偶一開始秀出的樣子


此外,如果你不會簡單的 DOS 指令,會有一些麻煩,請參考這裡。你只要會在 DOS 模式下,執行程式、拷貝、更改檔名、刪除檔案就可以了。執行程式是一定要會的,而其他的動作,在 Win 9x/OS/2 桌面下都可以做到。

此外為了以後的組譯方便,最好能寫個批次檔,請看第一章的例子。


註一:雖然 8088 運算速度很快,但是每執行一個指令總是要花一些時間,那麼每個指令掉底花多少時間呢?首先你得知道 8088 的工作頻率是 4.77MHz,這頻率是由主機板上的石英震盪器供給 8088 工作時計時用的,4.77MHz 的意義是一秒鐘內這個石英震盪器的內的石英振動了 4.77x106 次,也就是把一秒鐘分成 4.77x106 個時脈週期 ( 時脈週期英文是 clock cycle,簡稱時脈 ),因此每一個時脈週期花費 0.21 微秒 ( 1/4.77x106=2.1x10-7 )。假如你想查出下面的指令花費多少時間,

        add     ax,bx

可以到 http://zsmith.co/intel.html 網站中,在 The 8086 / 80286 / 80386 / 80486 Instruction Set 標題下,找到指令,ADD,的超連結,可以查得下表:

                         Clocks                 Size
        Operands     808x  286   386   486      Bytes

        reg,reg        3     2     2     1        2
        mem,reg      16+EA   7     7     3        2-4  (W88=24+EA)
        reg,mem       9+EA   7     6     2        2-4  (W88=13+EA)
        reg,immed      4     3     2     1        3-4
        mem,immed    17+EA   7     7     3        3-6  (W88=23+EA)
        accum,immed    4     3     2     1        2-3

亦即表示須花費 3 個時脈 ( 紅色字 ),亦即 0.63 微秒。由上可知,如果工作頻率越大,那麼每個時脈週期費時越短,CPU 執行指令也就越快。例如,Pentium 100 的工作頻率是 100MHz,亦即其石英震盪器每震盪一次花 0.01微秒 ( 1x10-8秒 ),比 8088 快了 20 倍。

註二:

如何取得 MASM 6.11d

取得 MASM 6.11d 至少有兩種方法。第一,可用搜索引擎尋找關鍵字「MASM download」,在許多網站中都可以下載 MASM 6.x 或 MASM 5.x,但這種做法往往涉及智慧財產權的法律問題,勿輕易嘗試。

第二,事實上,在微軟的網站就可以下載 MASM 6.11d,而且是免費的,只不過它是包含在 Windows 98 Device Driver Kit ( 98 DDK ) 堶情A整個工具約 25MB,但是我們只需其中一小部份,下載 BINS_DDK.EXE ( 2.5MB,如果這個檔案不見了,後面還有方法 ) 和 98SETUP.EXE (3.4MB) 這兩個檔案,放在同一子目錄,解開並安裝好後,在子目錄「\98DDK\bin\win98」奡N有 ML.EXE 與 ML.ERR 這兩個檔案,有了這兩個檔案就可使用組合語言了,這個版本就是 MASM 6.11d。

但是如果僅僅為了 ML.EXE 與 ML.ERR 這兩個加起來不到 400K 的檔案,就安裝 25MB 的 98DDK 似乎不合效益。底下有個免安裝 98 DDK 且能取得組合語言所需工具。在 BINS_DDK.EXE 奡N含有 MASM 6.11d 所需的最重要的兩個檔案,ML.EXE 和 ML.ERR。執行 BINS_DDK.EXE 後可得兩個檔案,Bins_ddk.cab 及 BINS_DDK.inf,而 ML.EXE 和 ML.ERR 就在 Bins_ddk.cab 檔案裡面,但檔名已被改成 BIN_WIN98_ML.EXE 和 BIN_WIN98_ML.ERR,所以你可以用 WinZip 或其他可以解壓縮的軟體就可以直接取出 BIN_WIN98_ML.EXE 和 BIN_WIN98_ML.ERR 這兩個檔案,再更改檔名即可,不必下載 98SETUP.EXE 和安裝整套 Windows 98 Device Driver Kit 了。在 Jon Kirwan: PC Assembly Programming 的網站有更詳細說明。但是不幸的是,微軟已不再支援 Windows 98 了,所以上面的網頁也已消失不見。幸好小木偶電腦中有一份,已上傳至 mega.nz,請按 下載。值得一提的還有,BINS_DDK.EXE 媮晱]含了許多有用的工具,但是檔名都不是慣用的名稱,需要更改,請參考下表:

在 BINS_DDK.EXE 的檔名 更改後的檔名備註
BIN_WIN98_ML.EXEML.EXE6.11d 組譯器
BIN_WIN98_ML.ERRML.ERR組譯錯誤訊息
BIN_WIN98_EXE2BIN.EXEEXE2BIN.EXE使 EXE 轉換成 COM 或 BIN 的工具程式
BIN_LINK.EXELINK.EXE5.12 版 32 位元連結器,如果你要製作 16 位元的程式,請不要用這個連結器,請用 LINK 5.36 版

MASM 8.0 與 MASM 64 位元版

微軟雖然已經不再單獨販售新版的 MASM,但是卻常常在某些產品中悄悄的包含新版的組譯器 ( 參考[賴榮樞]軟體資訊誌 ),例如在民國 95 年六月七日推出的 Visual C++ 2005 Express Edition 就包含了最新的組合語言組譯器,MASM 8.0,而且是免費的,可以到微軟的網頁中下載 MASMsetup.EXE。不過要安裝 MASM 8.0 卻必須要先安裝 Visual C++ 2005 Express 才行,幸好 Visual C++ 2005 Express 也是免費的。您可以到下載 vcsetup.exe,然後執行它,並連上網際網路,就可以開始下載並同時安裝 Visual C++ 2005 Express,然後再安裝 MASM 8.0。不過如果僅為了取得 MASM 8.0 就安裝整個 Visual C++ 2005 Express Edition 也不太有效率,在takira 的個人首頁中,有一種不須安裝 Visual C++ 2005 Express Edition 就能由 MASMsetup.EXE 抽取出 ML.EXE。另外,MASM 8.0 版內定產生的目的檔是 COFF 格式,所以如果你要製作的是 DOS 程式,得用「/omf」參數:

ml /omf filename.asm

此外 Windows Server 2003 SP1 DDK 包含了 MASM 8.0 版的 64 位元組譯器,可以組譯 64 位元的程式。取得方式是先到微軟的網中下載 Windows Server 2003 SP1 DDK 的光碟影像檔 ( ISO 格式 ),然後燒錄成光碟,在其 \common 子目錄堛 A64xdBINS.cab 就含有 ML64.EXE ( 版本是 8.0 built 40310.39 )。取出的方式是利用 WinZIP 或 WinRAR 等解壓縮軟體,將 A64xdBINS.cab 堜狾鹿仵袑挴縮,然後更改檔名。至於要更改成什麼檔名,在同一子目錄堛 A64xdBINS.inf 有提供線索。小木偶已將其寫成批次檔:

ren A64xdBINS_FILE_0  build.exe
ren A64xdBINS_FILE_1  c1.dll
ren A64xdBINS_FILE_2  c1xx.dll
ren A64xdBINS_FILE_3  c2.dll
ren A64xdBINS_FILE_4  cl.exe
ren A64xdBINS_FILE_5  lib.exe
ren A64xdBINS_FILE_6  link.exe
ren A64xdBINS_FILE_7  ml64.exe
ren A64xdBINS_FILE_8  msobj80.dll
ren A64xdBINS_FILE_9  mspdb80.dll
ren A64xdBINS_FILE_10 msvcp80.dll
ren A64xdBINS_FILE_11 msvcr80.dll
ren A64xdBINS_FILE_12 wmimofck.exe
ren A64xdBINS_FILE_13 clui.dll
ren A64xdBINS_FILE_14 linkui.dll

你可以把它存成批次檔,並存在 A64xdBINS.cab 解壓縮後的同一子目錄堙A然後在命令提示列下執行此批次檔,就可以得到 ML64.EXE。


回到首頁到第一章