亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

仿真器如何工作以及如何編寫?

仿真器如何工作以及如何編寫?

守著星空守著你 2019-11-21 10:14:48
模擬器如何工作?當我看到NES / SNES或C64仿真器時,我感到非常驚訝。http://www.tommowalker.co.uk/snemzelda.png您是否需要通過解釋特定的組裝說明來模擬這些機器的處理器?還有什么呢?它們通常是如何設計的?您可以為有興趣編寫模擬器(尤其是游戲系統)的人提供任何建議嗎?
查看完整描述

3 回答

?
森林海

TA貢獻2011條經驗 獲得超2個贊

仿真是一個多方面的領域。這里是基本思想和功能組件。我將把它分成幾部分,然后通過編輯填寫細節。我將要描述的許多內容都需要了解處理器的內部工作原理-組裝知識是必需的。如果我在某些方面不太清楚,請提出問題,以便我繼續改進此答案。


基本思路:

通過處理處理器和各個組件的行為來進行仿真。您構建系統的各個部分,然后像連接硬件中的電線那樣連接各個部分。


處理器仿真:

有三種處理處理器仿真的方法:


解釋

動態重新編譯

靜態重新編譯

使用所有這些路徑,您的總體目標是相同的:執行一段代碼來修改處理器狀態并與“硬件”進行交互。處理器狀態是給定處理器目標的處理器寄存器,中斷處理程序等的集合。對于6502,你有一個數代表寄存器8位整數的:A,X,Y,P,和S; 您還將有一個16位PC寄存器。


通過解釋,您可以從IP(指令指針-也稱為PC程序計數器)開始,然后從內存中讀取指令。您的代碼將解析此指令,并使用此信息來更改處理器指定的處理器狀態。解釋的核心問題是它的速度很慢。每次處理給定指令時,都必須對其進行解碼并執行必要的操作。


通過動態重新編譯,您可以像解釋一樣迭代代碼,但是不僅可以執行操作碼,還可以構建操作列表。到達分支指令后,您可以將此操作列表編譯為適用于您主機平臺的機器代碼,然后緩存此編譯后的代碼并執行它。然后,當您再次命中給定的指令組時,只需執行高速緩存中的代碼即可。(順便說一句,大多數人實際上并沒有列出指令,而是將它們即時編譯為機器代碼,這使優化變得更加困難,但這超出了此答案的范圍,除非足夠的人對此感興趣)


使用靜態重新編譯,您可以執行與動態重新編譯相同的操作,但是要遵循分支。您最終構建了代表程序中所有代碼的代碼塊,然后可以在沒有更多干擾的情況下執行代碼。如果不是以下問題,這將是一個很好的機制:


程序中不存在的代碼(例如,壓縮,加密,運行時生成/修改等)不會重新編譯,因此不會運行

已經證明在給定的二進制文件中查找所有代碼等同于停止問題

這些結合在一起使靜態重新編譯在99%的情況下完全不可行。有關更多信息,Michael Steil對靜態重新編譯進行了一些出色的研究,這是我見過的最好的。


處理器仿真的另一面是您與硬件交互的方式。這實際上有兩個方面:


處理器計時

中斷處理

處理器計時:

某些平臺-尤其是NES,SNES等較舊的控制臺-要求您的模擬器具有嚴格的時間安排以完全兼容。使用NES,您將擁有PPU(像素處理單元),它要求CPU在精確的時刻將像素放入其內存中。如果使用解釋,則可以輕松地計算周期并模仿正確的時間;通過動態/靜態重新編譯,事情變得很復雜。


中斷處理:

中斷是CPU與硬件通信的主要機制。通常,您的硬件組件會告訴CPU它關心的是什么中斷。這非常簡單-當您的代碼引發給定的中斷時,您查看中斷處理程序表并調用適當的回調。


硬件仿真:

模擬給定的硬件設備有兩個方面:


模擬設備功能

模擬實際的設備接口

以硬盤驅動器為例。通過創建后備存儲,讀取/寫入/格式化例程等來模擬該功能。這部分通常非常簡單。


設備的實際接口要復雜一些。這通常是內存映射寄存器(例如,設備監視用于執行信令更改的內存部分)和中斷的某種組合。對于硬盤驅動器,您可能有一個內存映射區域,您可以在其中放置讀取命令,寫入等,然后將這些數據讀回。


我會更詳細地介紹,但是您可以使用一百萬種方法。如果您在此處有任何具體問題,請隨時提出,我將添加信息。


資源:

我想,我已經給了一個很好的介紹在這里,但也有一噸的其他領域。我很樂意為您解答任何問題;由于巨大的復雜性,我在大多數情況下都非常模糊。


強制性維基百科鏈接:

仿真器

動態重新編譯

通用仿真資源:

Zophar- 這是我從仿真開始的地方,首先下載仿真器,然后最終掠奪其龐大的文檔檔案。這是您可能擁有的絕對最佳資源。

NGEmu-沒有很多直接資源,但是他們的論壇無與倫比。

RomHacking.net-文檔部分包含有關流行控制臺的機器體系結構的資源

仿真器項目參考:

IronBabel-這是.NET的仿真平臺,使用Nemerle編寫,可將代碼即時編譯為C#。免責聲明:這是我的項目,請原諒。

BSnes-一款出色的SNES模擬器,旨在達到周期完美的準確性。

MAME - 的街機模擬器。很好的參考。

6502asm.com- 這是一個帶有酷炫小論壇的JavaScript 6502模擬器。

dynarec'd 6502asm-這是我在一兩天內做了的一個小技巧。我從6502asm.com取得了現有的模擬器,并對其進行了更改,以將代碼動態地重新編譯為JavaScript,從而大大提高了速度。

處理器重新編譯參考:

該研究分為靜態重新編譯由邁克爾·斯泰爾(上面提到的)做過高潮本文,你可以找到源和這樣的在這里。

附錄:

自提交此答案以來已經過去了一年多的時間,并且得到了所有人的關注,我認為現在是時候更新一些東西了。


也許目前最令人興奮的事情是libcpu,它是由前面提到的Michael Steil啟動的。這是一個旨在支持大量CPU內核的庫,這些內核使用LLVM進行重新編譯(靜態和動態?。K哂芯薮蟮臐摿?,我認為它將為仿真做出巨大貢獻。


emu-docs也引起了我的注意,它包含一個很大的系統文檔庫,這對于仿真非常有用。我沒有花很多時間在這里,但是看起來他們有很多很棒的資源。


我很高興這篇文章對您有所幫助,并且希望我能在年底或明年年初完成有關該主題的書。


查看完整回答
反對 回復 2019-11-21
?
慕碼人2483693

TA貢獻1860條經驗 獲得超9個贊

仿真看似令人生畏,但實際上比仿真要容易得多。


任何處理器通常都具有寫得很好的規范,用于描述狀態,交互等。


如果您根本不關心性能,則可以使用非常優雅的面向對象程序輕松地模擬大多數較舊的處理器。例如,一個X86處理器需要某種東西來維護寄存器的狀態(簡單),某種東西來維護內存的狀態(簡單),并且需要接受每個傳入命令并將其應用于計算機的當前狀態。如果您確實想要準確性,那么您也可以模擬內存轉換,緩存等,但這是可行的。


實際上,許多微芯片和CPU制造商會先對芯片的仿真器然后對芯片本身進行測試,這有助于他們找出芯片規格或芯片在硬件中的實際實現方面是否存在問題。例如,可以編寫可能導致死鎖的芯片規格,并且當硬件中出現最后期限時,務必查看是否可以在規格中復制該規格,因為這表明比芯片實現中的問題更大。


當然,用于視頻游戲的模擬器通常關心性能,因此它們不使用幼稚的實現,并且還包括與主機系統的OS接口的代碼,例如使用繪圖和聲音。


考慮到舊視頻游戲(NES / SNES等)的性能非常慢,在現代系統上進行仿真非常容易。實際上,考慮到當這些系統流行時,免費訪問每個卡帶將是夢想成真的,您可以下載一套既有的SNES游戲,也可以下載任何Atari 2600游戲,這真是令人驚訝。


查看完整回答
反對 回復 2019-11-21
  • 3 回答
  • 0 關注
  • 502 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號