在編譯時為什麼使用分頁會導致覆蓋問題?

2021-09-26 19:53:27 字數 1769 閱讀 5324

這個問題困擾了我一天,結果在第二天早上醒來就想通了。

一切的一切,記得一句話分頁的虛擬位址是一維的,分段的虛擬位址是二維的

頁號x到頁表查,獲取到實際的物理頁a位址

實際位址是物理頁位址a+頁內偏移y,注意這裡是拼接,而不是加法

二維就是經過兩次對映後獲得的位址,分段模式中的段頁式的虛擬位址就是二維的,格式為段號 d + 段內偏移 y位址轉換的過程是:

3. 憑段號 d去段表查詢,得到頁號x

4. 憑頁號x到頁表查,獲取到實際的物理頁a位址

5. 實際位址是物理頁位址a+頁內偏移y

分頁

分段

這裡我一直看不懂,為什麼會發生碰撞或者稱為覆蓋問題?

編譯器在編譯程式的時候,只分配虛擬位址,此時與分頁或者分段模式沒有一點關係,這是編譯器的事

編譯器會給予各種段乙個基址——即所有段內的位址都是基於這個位址進行偏移。比如:資料段的基址是0xa,**段的基址是0xb,棧段的基址是0xc

隨著編譯的不斷進行,各個段都不斷增加內容,他們往同乙個方向增長。當某乙個段的資料增長特別多,就會觸及上乙個段的內容,就會導致乙個虛擬位址對應兩個內容:乙個是基址1+偏移量 1,乙個是基址2+偏移量2,當偏移量2比偏移量1大很多的時候,就會導致覆蓋問題。

簡單運算一下,假設base1+offset1 <= base2+offset2=>offset2-offset1 >= base1-base2,就是說當偏移量2比偏移量1相差base1 - base2就會導致覆蓋/重疊問題。

當分頁模式的時候就會把base1+offset1當作乙個虛擬位址,然後查頁表,當位移過大的時候就會侵略到其他段了。

如 頁面大小為 64k,虛擬位址a為1 + 65k,虛擬位址b為2 + 0k由於 65k > 64k ,所以就會接觸了 第 2頁裡面的內容了

當分段模式的時候,有以下幾個因素可以保證其不會出現重疊/覆蓋問題:

5.1. 段有大小,如果超過段則會報段溢位

5.2 不同的段會對映到不同的頁表,就是不同的段壓根他們不會在同一張頁表,所以即使offset2 - offset1 > 頁面大小也沒關係,因為他們不在同一張頁表

為什麼洗澡時你會靈感乍現

我們或許都有過這種經歷 你站在花灑下,溫暖細密的水珠噴灑全身。在一陣氤氳朦朧中,聽著淅淅瀝瀝的水聲,你突然靈光閃現,工作上遇到的難題有了個好對策 這種天降靈感也可能發生在別的時刻,比如長途開車 飯後散步 這些時刻有乙個共同特徵 你正做著一種重複呆板的工作,這種工作並不需要進行太多思考,而且,你手邊沒...

使用SqlParameter時引數為什麼要設定長度

sqlparameter的作用是用來傳參,以及防止sql語句注入的。以前在連線資料庫時,我都是像這樣做的。new sqlparameter name name d層 public class dao public datatable selectbyname string name dt sqlhe...

為什麼MySQL分頁用limit會越來越慢

目錄 阿牛新入職了一家新公司,第乙個任務是根據條件匯出訂單表中的資料到檔案中,阿牛心想 這也太簡單了,於是很快寫好了如下語句,並且告訴測試自己的 是免測產品。語句如下 select from orders where name lilei and create time 2020 01 01 00 ...