——記憶體是對一堆電晶體的連續抽象
別告訴我你不知道電晶體,也別說你不知道他的工作原理,否則請看:
每8個電晶體組成乙個位元組,每個位元組都有自己的位址,這個位址就是傳說中的記憶體位址,如果你在c中寫下如下的表示式(以下在未經特殊說明的情況下,均為c語言環境):
a = 0;
a是乙個符號,它有自己的真實位址,如果a是int型,並且在32位環境下,記憶體中將有4個位元組變為0值,符號a在編譯後將不復存在,替代它的將是乙個固定的位址(如果生明為全域性變數或者區域性static變數)或者乙個相對位址(函式內部的自動變數),這就是為何編譯後的程式,沒法還原為原始的程式**。
當你想要執行乙個程式,是作業系統把程式的映像讀入了記憶體,這個映像是有固定的格式的,(察看資料
)。每乙個正在執行的程式(在32位環境)擁有獨自的4gb記憶體,他也可以隨意的使用這4gb記憶體,事實上是可能,因為你的計算機不會安裝這麼大的記憶體,如果超出了物理記憶體用量,不經常使用的記憶體(系統有一種方法記錄記憶體的使用頻率),就會被分頁(寫入硬碟上的乙個檔案,xp一般都是pagefile.sys),分頁會導致系統執行效率成指數下降,所以程式的開發,仍然要顧及到記憶體的使用。
如果程式a和程式b同時訪問位址01000,會發生什麼?前面提到,每個程式都以為自己擁有整個足球場,所以a和b都會得到他自己想要的東西,而不會發生任何衝突,這就是虛擬記憶體技術從intel 386 cpu開始,這種技術已經開始發展,虛擬記憶體需要cpu和作業系統同時支援。
可能你碰到過這種情況,某乙個程式在執行時,突然蹦出乙個對話方塊,告訴你程式即將關閉,因為***xx記憶體不能寫入,這是因為,作業系統把記憶體分類——有的只能讀(程式段),有的可讀可寫(資料段),出現上述原因,可能是乙個未被初始化的指標指向了程式段,並且對指標指向的記憶體執行寫入的操作,於是作業系統不讓了,扔給你乙個保護錯誤。
但是,仍然有可能,在資料段上寫入一段有意義的程式,並且在函式返回,出棧的時候改變ip:cs指向為那一段有意義的程式(可能是乙個木馬,病毒的引導程式),這種方法,一般叫做緩衝區溢位攻擊,攻擊的方法各種各樣,就像雞蛋餅有各種做法,最初的gets()函式就被攻擊過,比如向乙個100個位元組的陣列中寫入200個位元組,後100個位元組剛好落在程式段,當然還有一些了不起的小技巧才能欺騙cpu去執行這段非法入侵的**。
程式設計之記憶體分配問題
1.字元 char str 10 sizeof str 為10 char pstr str,sizeof pstr 為4 與 char c 等價,前者字串常量的最後由系統加上乙個 0 也等價char c 10 是否需要加 0 完全根據需要決定,但是由於系統對字串常量自動加乙個 0 因此,人們為了使處...
C C 程式設計之記憶體管理
1 從 全域性 靜態儲存區域分配 內存在程式編譯的時候就已經分配好,這塊內存在程式的整個執行期間都存在,例如,全域性變數,靜態變數。2 常量儲存區 儲存程式中的常量。3 棧區 在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結束後這些儲存單元自動被釋放。棧記憶體分配運算內置於處理器...
C C 程式設計之記憶體管理
記憶體分配方式 c語言中記憶體分配方式 1 從 全域性 靜態儲存區域分配 內存在程式編譯的時候就已經分配好,這塊內存在程式的整個執行期間都存在,例如,全域性變數,靜態變數。2 常量儲存區 儲存程式中的常量。3 棧區 在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結束後這些儲存單元...