摩托羅拉68000
![本頁使用了標題或全文手工轉換](http://images.weserv.nl/?url=//upload.wikimedia.org/wikipedia/commons/thumb/c/cd/Zh_conversion_icon_m.svg/35px-Zh_conversion_icon_m.svg.png)
此條目需要補充更多來源。 (2019年12月3日) |
![]() | 此條目需要精通或熟悉相關主題的編者參與及協助編輯。 |
摩托羅拉68000型中央處理器,或稱MC68000,680x0,m68000,m68k,68k;是由美國摩托羅拉公司(Motorola)的半導體部門(現已獨立成為飛思卡爾公司(Freescale))出品的一款16/32位元CISC(複雜指令集)微處理器。作為M68K處理器系列的第一個成員,MC68000於1979年投放市場。由於內部使用32位元匯流排和暫存器,它在軟體層(指令集)上基本與隨後的純32位元產品保持相容。
![](http://images.weserv.nl/?url=//upload.wikimedia.org/wikipedia/commons/thumb/2/28/XC68000.agr.jpg/250px-XC68000.agr.jpg)
實體記憶體
歷史
摩托羅拉公司於1976年起動MACSS計畫(Motorola Advanced Computer System on Silicon,摩托羅拉矽晶進階電腦系統),打算開發一款與以前產品完全不相容的全新微處理器。根據計劃,新CPU應該是對當時摩托羅拉主流8位元CPU6800的一個高階互補產品,而不會考慮兩者間的相容性。不過,當68000設計出來後,它還是被保留了一個可相容6800外部的匯流排協定模式,並且專門有8位元匯流排的產品被生產出來。當然,設計人員還是更在意於其向下相容性,這為68000確立在32位元CPU領域的領先優勢奠定了基礎。比如,68000使用32位元暫存器和內部匯流排,僅管其本身的結構很少直接操作長字。小型電腦諸如PDP-11和VAX—二者採用了類似的微編碼—對68000的設計有深遠的影響。
在20世紀70年代中期,8位元微處理器製造商紛紛競爭匯入下一代16位元CPU。國家半導體在1973年到1975年間首先開發出了IMP-16和PACE,但其速度並不理想。英特爾公司於1977年推出8086,迅速受到歡迎。此時,為確保競爭上的領先,摩托羅拉意識到其MACSS計劃必需跳過16位元系統,而直接推出16/32位元混合型CPU。到1979年,摩托羅拉68000,即MC68000,才告姍姍來遲。由於比8086晚兩年,其電晶體數目更多,並因其易用性得到了好評。
最初的MC68000使用3.5微米HMOS技術(即高效能N通道金氧半導體,CMOS的前身)製造。1979年發布了工程樣品,次年產品型面世,速度有4、6、8、10MHz多種。最快的16.67MHz版本到80年代末才面市。
MC68000在早期得到了很多高階產品的青睞。在昇陽公司的Sun workstation等多種Unix工作站中,MC68000一度占領導地位。市場領先的其他一些電腦,包括Amiga(阿米加)、Atari ST(雅達利ST)、Apple Lisa (蘋果Lisa)和 Macintosh(麥金塔),以及第一代雷射印表機,如蘋果公司的LaserWriter,都使用MC68000。1982年,摩托羅拉進一步更新了MC68000的指令集以支援虛擬記憶體,並使其能夠符合由Popek和Goldberg於1974年提出的虛擬化標准。
為支援低成本系統和使用較少記憶體的應用,摩托羅拉於1982年還推出了面向8位元外部匯流排的MC68008。1982年以後,摩托羅拉開始把更多的注意力投向68020和88000。
其他製造商
由日立公司設計,1985年兩公司聯合推出了使用CMOS技術的68HC000。68HC000的速度有8到20MHz多個版本。儘管除了使用CMOS電路,68HC000與基於HMOS的MC68000完全一致,但正是因此其能耗得到大幅下降。MC68000在25攝氏度環境下能耗大約為1.35瓦,而8MHz的68HC000則為0.13瓦,較高頻率的版本則能耗也相對提高(HMOS技術則不同:其在CPU空閒時仍會耗電,所以功耗與頻率基本無關)。後於1990年摩托羅拉又推出了MC68008的CMOS版本,並將其改進為可相容8/16位元兩種匯流排模式。
其他HMOS版68000的製造商包括:Mostek、Rockwell(洛克維爾)、Signetics、Thomson(湯姆遜)和東芝。東芝也生產CMOS版68000(TMP68HC000)。
應用
68000首先被應用於許多高端產品中,如多使用者微型電腦WICAT 150及阿爾法微系統的一些早期電腦等。單使用者工作站如惠普公司的HP 9000/200、昇陽電腦的Sun-1;圖形終端如DEC的VAXstation 100和Silicon Graphics的IRIS 1000均使用68000。許多Unix系統也開始使用68K系列CPU。
在80年代中期,68000又成為首先應用於個人/家庭電腦的CPU。先後有蘋果公司的Apple Lisa與麥金塔(Macintosh 128K)、Amiga的海軍准將(Commodore)、雅達利ST及夏普的Sharp X68000採用68000。
68000最主要的成功在於控制器領域。早在1981年Imagen公司就把68000用作其雷射印表機Imprint-10外部控制器的CPU。惠普於1984年發布的第一款LaserJet印表機亦使用一片8MHz的68000作為內建控制器。類似的基於68000的整合控制器也被廣泛用在其他多款印表機中。到90年代,68000仍在許多低階印表機中被使用。
除了傳統商業和家用計算應用,68000在工業控制系統中也取得了巨大成功。Allen-Bradley、德州儀器及西門子公司生產的可程式化邏輯控制器(PLC)即使用68000。一般來說,這類工業系統的使用者更重視產品的可用性,而不是向家庭使用者一樣過於在意其是否過時。所以,仍有許多使用68000的系統,在被安裝二十多年後,在生產一線提供著持續而可靠的服務。
隨著技術的進步,68000在電腦單機市場漸被淘汰,但其應用仍活躍於消費和嵌入式領域。遊戲機製造商使用68000作為許多街機和家用遊戲機的處理器。雅達利在1983年推出的Food Fight便是使用68000的代表街機遊戲。世嘉的System 16、卡普空的CPS-1和CPS-2以及SNK的Neo Geo MVS也都使用68000。
在80年代末到90年代初,一些遊戲機廠商使用68000作為家用遊戲平台的中央處理器。這包括世嘉的Mega Drive(MD)、Neo Geo AES和Super A'Can。到了90年代,儘管街機遊戲開始使用更加強大的CPU,68000還在世嘉的32位元CPU遊戲機Sega Saturn中用作聲音控制器。
基於68000的683XX系列微控制器則廣泛應用於許多應用領域中,包括網路和電話裝置、電視機機上盒、實驗室與醫療裝置等。思科、3Com等公司曾在他們生產的通訊裝置中使用MC68302及其衍生產品。Palm公司曾使用DragonBall系列CPU(68K系列的後續)作為其PDA的處理器,直到基於RISC的ARM處理器開始統治PDA市場。此外,AlphaSmart公司在其可攜式文書處理器中使用DragonBall。
德州儀器在一些高端繪圖計算機,如TI-89和TI-92中,使用68000。這些裝置早期使用以68EC000為核心的專門化微控制器,後來則改用封裝好的MC68SEC000。
作為微控制器核心
在被純32位元CPU取代後,68000開始被用作許多微控制器的核心。1989年,摩托羅拉發布了MC68302通訊處理器。兩年後又推出獨立處理器晶片MC68EC000。1996年的MC68SEC000便使用了這款晶片。
1996年摩托羅拉停產HMOS MC68000和MC68008,但其分離出來的半導體部門,飛思卡爾公司,仍在生產MC68HC000等68K家族系列產品。68000架構的後代,680x0、CPU32以及Coldfire系列,也仍在生產。
架構
位址匯流排
68000位址匯流排為24位元,故支援16MB最大實體記憶體。在使用32位元寬度對位址進行儲存和計算時,高位的一個位元組會被自動忽略。這種設計使得其具備相當的向前相容性,可以直接執行為後續的純32位元CPU編寫的軟體。也因此,根據現今的定義,68000應稱得上是一款32位元CPU。摩托羅拉使用32位元內部匯流排的目的在於希望能夠在68000上編寫可以被將來的後續產品直接使用的軟體,而相關指令不必作位數上的調整。
然而,程式工程師還是有可能編寫出無法與後續產品相容的軟體。倘若這種24位元軟體丟棄高位位元組,或將該位元組用作定址以外的目的,它就有可能在32位元68K系列CPU上執行失敗。這就是說,對於希望支援向前相容的軟體,必須始終使用32位元寬度定址,並且將最高位位元組置零。
內部暫存器
68000包含8個32位元通用暫存器(D0-D7),及8個32位元位址暫存器(A0-A7)。最後一個位址暫存器,即A7,也作為標準棧指標使用,在編程中可以使用SP作為同義詞。這組暫存器在規模上恰到好處:既可以對中斷快速反應(只有十多個暫存器要儲存),也有足夠的暫存器來進行快速計算。
儘管兩種暫存器並存有時會比較麻煩,但在實踐中並非難於掌握。據稱,這還使得CPU的設計者們可以通過對位址暫存器組使用輔助計算單元,從而實現較高程度的並列機制。
儲存內容高位位元組在前(Big Endian模式),與x86相反。
狀態暫存器
68000比較、算術和邏輯操作會在狀態暫存器SR的低階位元組(又稱CCR)中設定一些標誌位,以供之後的條件跳躍使用。這些標誌位是:得零(Z)、進位(C)、溢位(V)、擴充(X)、負數(N)。儘管許多時候值是相同的,X與C依然是兩個不同的標誌位。這就允許算術、邏輯和移位元運算的多餘位與邏輯控制/連接造成的進位區別開。
指令集
68000的指令集基本上是正交的。大部分指令被劃分成操作和位址模式兩部分,並且大部分位址模式都對幾乎全部指令可用。這種近似正交性在編程人員當中毀譽參半。
編程者會清楚地發現,他/她所書寫的指令可能被組譯成幾種不同的二進制操作碼。這實際上是一種不錯的妥協:一方面,在便利性上與純粹的正交指令系統相仿;一方面,CPU設計者可以有更多的自由來設計操作碼表。
對於一台16位元時代的機器而言,由56條指令構成的最小指令集仍顯巨大。此外,許多指令和定址模式會在指令後邊加入位址/定址模式碼。
許多設計者確信MC68000體系結構應基於成本考量使用較精簡的指令碼,特別是使用編譯器自動生成時。這種認識為對其設計上的成功加分不少,並且使之成為一種經久不衰的體系結構。這一信條持續地保證了整個系列指令集的設計優勢,直到ARM體系結構引入同樣精簡的Thumb指令集。
特權級
68K系列CPU包含兩個特權級。超級使用者(supervisor)模式和使用者(user)模式。後者相比於前者只是禁用了中斷級控制。中斷總會使CPU進入超級使用者態。超級使用者標誌位儲存於狀態暫存器SR中,並對使用者可見。
超級使用者態下會有一個分離的棧指標用於中斷處理。
中斷
68000可以辨識7級中斷,從級別1到級別7。7級中斷嚴格按優先級排列,一個進階中斷總是能巢狀於一個低階中斷。可以使用專門的特權指令在SR內設定最小中斷級別,從而封鎖所有小於此級別的中斷。但如果設定為0,表示不接受中斷。級別7不可被封鎖,即NMI。級別1總是可以被進階中斷打斷。
硬體中斷源將中斷訊號以編碼方式通過三條輸入線傳送給CPU。一般會使用專門的中斷控制器來匯總各外部裝置,並將中斷訊號按級編碼與CPU硬連。中斷控制器可以使用簡單如74LS148優先級編碼器,複雜如MC68901多功能外設(支援可程式化中斷控制、通用非同步收發裝置、定時器及並列輸入輸出等)等各種電路模組。
在主記憶體低1K位置儲存中斷向量表,共支援256條中斷向量。部分中斷向量有特殊用途:向量1為初始棧位址;向量2為初始代碼位址;向量3到15用於錯誤報告,包括匯流排錯誤、定址錯誤、非法指令、除零異常、優先權違反等。從向量24起處理真正的中斷,包括偽中斷、針對級別1到級別7的預設處理向量,多達15個自陷向量,以及使用者定義向量。
由於必須在重新啟動時保證向量1和2的內容有效,所以68000系統通常包含在位址底部使用非揮發性記憶體(如ROM)來儲存一些常式向量和啟動代碼。但是,一個通用電腦的作業系統會期望在執行時改變向量內容。解決辦法是將ROM內的向量指向RAM的分支表,或使用早期在8位元CPU中廣泛使用的換頁技術(Bank switching)。
由於包含一條非特權指令MOVE from SR,允許一般使用者唯讀地訪問某些特權狀態,68000並未完全滿足波佩克與戈德堡虛擬化需求。該需求指出了為構建某一CPU之等價虛擬機器而對CPU提出的若干要求。
MC68000對虛擬記憶體缺乏方便的支援。一款支援虛擬記憶體的CPU應能在主記憶體訪問失敗後自陷並恢復。不過,68000確實提供了一個匯流排錯誤異常來使CPU自陷,儘管還不能儲存足夠的狀態資訊以便於例外處理之後的恢復。為此,一些Unix工作站通過使用兩塊68000來解決虛擬記憶體問題。兩塊CPU的執行時鐘存在相位差。當第一塊遇到定址異常後,特殊的硬體會設法向第二塊發出中斷,以防止其也訪問錯誤位址。中斷常式在第二塊CPU上處理完主記憶體換頁後,會按之前的狀態重新啟動第一塊CPU,從而再次使兩CPU同步。
不過,以上這些問題在MC68010被徹底解決。在MC68010中,匯流排異常和位址錯誤均會使大量狀態資訊壓入系統棧,以便於之後的恢復。MOVE from SR也被修正為特權指令。原本用於訪問SR低階位元組的代碼可由新指令MOVE from CCR取代。
指令集細節
標準定址模式
68000提供多種定址模式,並統稱為有效定址(EA)。在CPU參考手冊中,經常會有諸如MOVE <ea>,<ea>這樣的表記方式。這表示在目的運算元和源運算元上可分別使用一種(但通常不是全部)有效定址。
- 暫存器直接定址
- 資料暫存器直接定址,如D0。
- 位址暫存器直接定址,如A0。通常不使用A7。
- 暫存器間接定址
- 簡單間址,如(A0)。先取得A0所儲存的位址,再在主記憶體中該位址處取出資料。
- 自增間址,如(A0)+。只能用於源運算元域。先取得A0所儲存的位址,再在主記憶體中該位址處取出資料,然後A0的內容(位址)自增一定長度(因指令字尾而定)。這個操作其實相當於x86中的出棧指令POP(注意棧的方向和主記憶體方向相反)。在這裡,A0被用作一個使用者自訂的棧指標,與系統使用的A7/A7'不同。
- 自減間址,如-(A0)。可用於源或目的運算元域。先將A0的內容(位址)自減一定長度(因指令字尾而定);然後取得A0所儲存的位址,再在主記憶體中該位址處存入資料,然後這個操作其實相當於x86中的入棧指令PUSH。[1]
- 偏移間址,如2AFF(A0)。前邊的偏移量為16位元。實際取得的位址為(A0)+2AFF。
- 加索引的偏移間址,如E3(A0, D0)。前邊的偏移量為8位元。實際取得的位址為(A0)+(D0)+E3。
- 程式計數器位移
- 長位移,如2AFF(PC)。前邊的偏移量為16位元。PC變為(PC)+2AFF。
- 短位移,如E3(PC, D0)。前邊的偏移量為8位元。PC變為(PC)+(D0)+E3。
- 絕對主記憶體定址
- 直接使用主記憶體位址值,如$4000,表示目標位址在主記憶體位址為4000處。注意$表示後邊所跟數字為16進制,%表示2進制。
- 在實際編程中,可以使用代碼中的標號來充當主記憶體位址值。組譯器會自動翻譯為數字位址。
- 注意不應與立即數混淆。使用立即數時應在值前再加一個#。$4000表示16進制位址4000;#$4000表示16進制立即數4000;4000表示10進制位址4000;#4000表示10進制立即數4000。
指令字尾
大部分指令都有表示操作長度的字尾:.B、.W或.L,分別表示這一操作在位元組(8位元)上、字(16位元)上或長字(32位元)上進行。運算的過程和結果都會受到字尾的影響。在運算過程中,只有屬於操作長度範圍的部分才會參與運算。比方說,執行MOVE.B D2,D1會把D1的最低一位元組複製到D2的最低一位元組處,而兩者的其餘位元組均不受影響。對於CCR,各標誌位的值會由操作長度的最高有效位決定。如果某次ADD.B使得結果的第7Bit位為1,則CCR的N位會置1;如果某次ADD.L使得結果的第7Bit位為1,並且第15Bit不為1,則CCR的N位不會置1。在後一種情況下,CCR的N位只受第15Bit,即一個字的最高有效位影響。另一個例子是在自增/自減定址中,自增/自減的長度因操作字尾而異。如果操作為MOVE.B,則自增/自減1;W為2;L為4。
常用指令
大部分68000的指令都是二元的。目的運算元在前,源運算元在後。
- 移動指令
- MOVE:標準移動指令。另有一些其它移動指令供選擇:MOVEA(移動到位址暫存器An,不會影響CCR,但字尾不可為.B)、MOVEQ(移動一個8位元數到目標暫存器,因為可將數值直接寫入指令故稱快速移動)、MOVEM(移動暫存器組到指定堆疊,多用於中斷/子程式處理的第一步)等。
- LEA:移動一個位址值到目標暫存器。
LEA $2000,A0
表示將A0的值設為16進制的2000。應注意此時不加立即數標誌#。 - LINK/ULNK:建立/取消堆疊框。這個指令用於翻譯高階語言的函式呼叫。
LINK An, #-x
可將An作為函式棧指標,並SP所指向的使用者棧內取得x大小的空間儲存局部變數,之後SP仍將指向棧頂,而An指向棧頂+x的位置。x的值在編譯時由編譯器自動算出。
- 算數指令:ADD(加)、SUB(減)、MULU /MULS(無/有符號乘)、DIVU/DIVS(無/有符號除)、NEG (取補)、及CMP(類似於減但只會影響標誌位而不改變運算元)。算數指令也多成組提供。對於ADD,還有ADDA(加位址,不會影響標誌位)、ADDI(加立即數)、ADDQ(快速加,加數不大於8以便於直接放在操作碼中,比x86的INC指令書寫麻煩但功能更強)、ADDX(影響進位符,用於大數運算)等。
- BCD碼算數指令:ABCD(加)和SBCD(減)。
- 移位指令
- 邏輯移位(移位後用0補充):LSL(左移)、LSR(右移)
- 算數移位(移位後用原來最高/最低有效位補充):ASL(左移)、ASR(右移)
- 迴圈移位(移位後用所移動位補充):ROL(左移)、ROR(右移)
- 迴圈擴充移位(移位至CCR的X位,同時用之前的X位補充):ROXL(左移)、ROXR(右移)
- 位元運算指令:BSET(置1)、BCLR (清0)和BTST (如果測試位在改變前為0則將CCR的Z設為1)。
- 多工處理:TAS(測試並置位)。這個指令用於實現訊號燈等同步機制。
- 流程控制:JMP(無責任跳躍)、 JSR (跳躍至次常式)、BSR (按相對位址跳躍至次常式,多用於跳躍至使用者定義常式)、RTS (從次常式返回)、RTE (從異常/中斷中返回)、 TRAP(自陷,即軟中斷)、CHK(檢查位址是否越界,如是則觸發異常)。
- JMP指令只是純粹跳躍,不會將下一條指令位址推入堆疊;JSR和BSR會將下一條指令推入堆疊。
- RTS將棧指標指向內容彈出給PC。
- 條件測試並跳躍:Bcc系列指令。cc定義了所測試的條件位。常用的如:
- BNE:不等於時跳躍。
- BEQ:等於時跳躍。
- BRA:無條件跳躍。
參考文獻
- ^ Alan Clements《Principles of Computer Hardware》Fourth Edition Pg254.