-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Chi-En Wu
committed
May 2, 2017
1 parent
623b727
commit f2d24b4
Showing
2 changed files
with
14 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# 3.4.1. 自我修改的程式碼 | ||
|
||
在電腦時代的早期,記憶體是很珍貴的。人們不遺餘力地減少程式的大小,以為程式資料騰出更多的空間。一個經常使用的技巧是,隨著時間改變程式自身。偶爾仍舊會找到這種自我修改的程式碼(Self Modifying Code,SMC),如今多半是為了效能因素、或者用在安全漏洞上。 | ||
|
||
一般來說應該避免 SMC。雖然它通常都被正確地執行,但有著並非如此的邊界案例(boundary case),而且沒有正確完成的話,它會產生效能問題。顯然地,被改變的程式碼無法維持在保存被解碼指令的追蹤快取中。但即使程式碼完全(或者有時候)不會被執行,因而不會使用到追蹤快取,處理器也可能會有問題。若是接下來的指令在它已經進入管線的期間被改變了,處理器就得丟掉大量的成果,然後從頭開始。甚至有處理器的大多狀態都必須被丟棄的情況。 | ||
|
||
最後,由於處理器假定––為了簡化起見,而且因為這在 99.9999999% 的情況下都成立––程式碼分頁是不可修改的(immutable),所以 L1i 的實作不會採用 MESI 協定,而是一種簡化的 SI 協定。這表示,若是偵測到了修改,就必須做出許多的悲觀假設。 | ||
|
||
強烈地建議盡可能避免 SMC。記憶體不再是如此稀有的資源。最好是撰寫各自的函式,而非根據特定的需求修改一個函式。或許有天 SMC 的支援能夠是可選的,而我們就能夠以這種方式偵測出嘗試修改程式碼的漏洞程式碼(exploit code)。若是真的必須使用 SMC,寫入操作應該要繞過快取,以免因為 L1i 所需的 L1d 的資料造成問題。關於這些指令的更多訊息,見 6.1 節。 | ||
|
||
在 Linux 上,識別出包含 SMC 的程式通常非常容易。使用正規工具鏈(toolchain)建構的話,所有程式的程式碼都是防寫的(write-protected)。程式設計師必須在連結期(link time)施展強大的魔法,以產生程式分頁能夠被寫入的可執行檔。當這種情況發生時,現代的 Intel x86 與 x86-64 處理器具有專門的、計算自我修改的程式碼使用次數的效能計數器。 | ||
有了這些計數器的幫助,非常輕易就能夠識別有著 SMC 的程式,即使程式由於寬鬆的許可而成功執行。 | ||
|