為什么一塊四十多年前的輔助芯片,能讓浮點運算提速上百倍,還奠定了今天所有處理器的浮點標準?
1980年,英特爾推出了8087浮點協處理器。它把浮點運算速度提升了100倍,同時引入了一套浮點格式和算法規范,至今仍是現代處理器浮點單元的設計基礎。這顆芯片的內部,用微碼實現平方根、正切、指數等復雜函數,每一處設計都值得重新審視。
![]()
最近,一個叫Opcode Collective的團隊開始對8087的微碼進行逆向工程。他們打開芯片封裝,在顯微鏡下采集了高分辨率圖像,一塊占據中心位置的龐大微碼只讀存儲器暴露出來。這片ROM存有1648條微指令,就是它們控制著8087的全部指令集。每條微指令長16位,能完成數據搬移、加法、移位等基本操作,所有復雜函數最終都由這些細微動作組合而成。
![]()
在這個帖子里,我想帶你看一條看似微不足道的指令——FXCH,也就是浮點寄存器交換。直覺上,交換兩個寄存器的內容應該很簡單,但微碼卻動用了14條微指令。為什么要這么多?這就要從芯片內部的寄存器結構和棧控制邏輯說起。
8087芯片有兩個臨時寄存器和八個棧寄存器,每個寄存器同時存放一個數的指數部分和尾數部分。指數走16位數據通路,尾數走64位數據通路。此外,每個寄存器還有兩個標簽位,用來標記所存數值的類型——比如是有效數、零,還是特殊值。芯片右側的棧控制電路則負責維護棧頂位置,當數據壓棧或出棧時,準確跟蹤哪一個是棧頂。
微碼執行FXCH時,并不是粗暴地交換全部位,而是分步處理指數、尾數和標簽,還要同步更新棧控制狀態。因為8087的棧寄存器本質上是一個循環棧,物理位置不變,邏輯位置由棧頂指針定義。交換兩個邏輯寄存器的同時,必須保證棧頂指針仍然指向正確的位置,同時標簽信息不能錯位。于是,微碼先用幾個周期把第一個寄存器的指數和尾數搬進臨時寄存器,再把第二個寄存器的內容搬到第一個,最后從臨時寄存器寫回第二個,期間每一步還需插入調整標簽和棧指針的微操作。
![]()
有意思的是,8087的微指令體系存在大量特例和臨時性功能。比如有的微指令會根據標簽位自動跳過某些步驟,有的則能觸發條件跳轉,形成循環。FXCH用到的14條微指令中,部分就嵌入了這種條件邏輯,并非直線執行。這使得一個“交換”動作,在微碼層面變成了一次包含判斷、搬運和同步的微型流程。
今天重看8087的內部實現,依然能感受到一種硬件資源極度受限時的精巧。當年的設計者沒有把“簡單指令就應該簡單”當成教條,而是讓每一條指令都服從棧體系、標簽體系與數據通路的統一節奏。也正因如此,8087才能在5微米工藝上跑出令人吃驚的浮點性能,并把IEEE 754浮點標準的雛形推向前臺。而Opcode Collective的逆向工作,正在讓這些已經凝固在硅片里的設計思路重新流動起來。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.