32位的cpu只能定址4GB的內存空間,那麼硬碟,flash這些存儲設備是如何定址的的?cpu怎樣讀取其中某個地址的數據?
感覺好像答過類似的問題(32位最大內存利用只能是4G嗎,但是8位的單片機他是用2Byte做地址的啊,可以定址64K的,? - 知乎)
1. 定址範圍=定址單元大小*定址字長 2. 定址字長與CPU字長無直接關係
存儲設備(比如SATA)的定址字長都能達到48位,定址單元大小是512位元組,算下來就是2^48*512=131072TB,足夠訪問設備用了。
跟MMU沒關係。
---------------------------------
題主看來想知道讀的細節:存儲設備訪問一般都是發SCSI命令,對於讀命令來說,有READ6/READ10/READ12/READ16/READ32這些SCSI命令,這些命令有一定格式,其中包含有要訪問的設備塊號(LBA:Logical Block Address)。
READ10命令里的LBA長度是4位元組,最大定址範圍是4G,乘以512位元組的扇區長度的話,就可以訪問2T以內的磁碟空間:
超過2T的話,就要用更新一點的指令了,比如READ16:
塊號範圍是2^64,乘以512位元組扇區長度的話,其表示範圍最大是2^73位元組(9,444,732,965,739,290,427,392),就目前來看,已經足夠用了。
發送命令的時候,還順便會告訴設備要讀多少東西,以及讀的東西放到什麼內存位置,有了這些信息以後,磁碟控制器會把正確的數據放到指定的位置上,然後CPU就可以訪問了。
SCSI命令參考:https://www.seagate.com/files/staticfiles/support/docs/manual/Interface%20manuals/100293068j.pdf
大家都沒看到題主的「cpu怎樣讀取其中某個地址的數據」這個問題么……沒人真正的回答這個問題……
其實也不複雜,所有的外圍設備,包括硬碟啦,快閃記憶體啦,PCI設備啦,PCIE設備啦之類的,裡面的可訪問內容(硬碟,快閃記憶體,顯存,音效卡內存等等)都不是直接映射在CPU地址空間里的
這些設備會提供一個Interface,所有的這些設備都會在內存空間中佔用很小的一塊地址(通常是數十位元組)作為IO映射地址,比如你想訪問硬碟中的某一段數據,你需要往SATA控制器所在的IO埠寫入命令(通常是ATA/SCSI命令),說「我要讀取第x設備的第y扇區~第z扇區的內容」,然後連續讀取從該IO埠返回的內容——那是不可能的,那是上古時代PIO模式需要的方法。
正如 @Bluebear 所說,現代的SATA控制器都可以直接進行DMA訪問,會直接把所需要的數據自動寫入指定好的內存地址,然後發一個中斷告訴CPU已經完成了,CPU就可以使用這些數據了。
所以答案是CPU不能直接讀取外存中某個地址的數據,需要經過SATA控制器-硬碟控制器發送一系列命令才可以
另外,顯存比較特殊(其實PCI系設備都有這個功能,只是基本只有顯卡在用),它可以映射一段顯存地址到CPU的地址空間里,被映射的部分就是可以被CPU直接訪問的部分
另:32位的x86CPU實際上有36位地址線,實際可定址範圍是64GB
CPU不能直接訪問硬碟/Flash上面的數據。
早期的CPU訪問硬碟數據的過程是:
1、查找硬碟控制器地址(這個地址在32位系統中,在4G範圍內)
2、把要訪問的數據在硬碟中的地址(LBA)和數量傳遞到硬碟控制器的地址
3、硬碟控制器吧上述數據從硬碟中讀取出來,並寫入到內存中。
4、CPU從內存中訪問這段數據。
後來有了DMA,在第3步的時候,CPU可以去干別的事情。
其它的,其它答案裡面有提到的,就不贅述了。
首先要明白一個概念cpu的指令是直接操作內存的,簡單來說在硬體上的表現就是數據線輸入輸出數據,地址線輸入輸出地址。
那第一個問題,是不是32位cpu只能受限於定址4G的地址空間呢,其實這個看法是不對的,這個跟cpu的數據匯流排有關,舉個原始點的好懂的例子,很早以前16位的cpu是不是只能定址2^16=65K地址呢,答案是並不是,在intel 8088時代就可以支持到1M的內存,8088是個16位cpu,但是地址匯流排是20位,那多出來的4位怎麼協調各種寄存器處理好呢,這就引出了萬惡的段寄存器,cs,ds,ss,es,完整訪問一個地址需要一個段寄存器左移4位加上另一個16位偏移,正好構成了20位1M地址的完整訪問。那麼我們到32位系統來看,intel 80486 就已經32位的cpu+36位地址線了,為了實現向下兼容,此時萬惡的段寄存器進化成了選擇符,在保存特定結構定義下,可以由選擇符加偏移訪問完整的4G空間,不同選擇符可以定義訪問不同的或重疊或獨立空間,理論可以完整訪問36位64G空間的,另外分段中還有分頁,分頁機制也可以支持訪問64G空間,那為什麼我們一般在32位操作系統中貌似只能訪問4G空間呢,其實是受限於32位操作系統架構,這個就不深入了,但是還是要強調,並不是32位系統真正訪問不是64G內存,無論是windows還是linux都有一個叫PAE的機制,開啟這個機制是將頁表從二級分頁改為三級,是可以通過特殊系統調用訪問到的。這些都是intel花里胡哨的複雜處理方式,像單片機或者arm的一些定長指令或者簡單指令集,一般數據匯流排和地址匯流排是一致的,所以就沒那麼複雜。第二個問題硬碟或者flash是怎麼定址的,這個跟內存的方式完全不一樣,撇開dma及某些方式的地址映射,這是cpu另一種工作方式,叫作I/O定址,這種方式並不是像cpu地址數據這樣並行簡單操作,而是要依據特定的協議來讀取的,這是一種軟硬體協同的工作方式,具體能訪問多大空間這都是介面和協議規則。32位的確是只有4G空間,但是硬碟不是直接通過這4G地址空間讀取的,而是把硬碟設備映射到到一個地址上,通過這個地址對硬碟進行操作,讀啊,寫啊,現在都是DMA,CPU要讀寫硬碟內容的話需要像這樣 CPU--內存--硬碟。
硬碟的定址方式一般是LBA(邏輯塊定址)。就是說硬碟被劃分成一個一個的「block」,每個block都有一定的數據(比如512 bytes),一個block對應一個地址,叫做lba地址。cpu是通過這個地址指定要讀寫的塊的。
操作系統在需要硬碟幹活的時候會通過特定的協議告訴硬碟:
把哪些邏輯塊的數據複製到內存的哪些位置;
或者把內存哪些位置的數據複製到硬碟的哪些塊。然後就是硬碟在讀寫內存的時候cpu會用一定的方式和硬碟「分時地」共享匯流排,這個鍋具體怎麼分我也不知道,不過有一點就是在這期間cpu不能一直掌握內存的控制權。
然後硬碟在做完了一件事之後會發中斷通知cpu它做完了。
差不多就是這樣。一句話回答:因為硬碟、flash這些存儲設備不算「內存」。
能被CPU直接定址到的才算到內存里。
這些「外存」,或者更泛的說「外設」,並不是直接由CPU定址處理的。
他們的工作通過「驅動程序」進行。驅動程序的工作模式可以很多種,比如IO模式或者DMA模式。但從根本上就是一段工作在內存中的代碼,其指令、數據通過CPU的內存定址和中斷方式被CPU調度。
硬碟是I/O設備。訪問硬碟等設備是用另外一種方式,根本不受4G定址限制。
實際上,CPU字長和定址空間並沒有必然因果關係。如果你學過很古老的8086/8088彙編就會知道,地址匯流排寬度不一定等於字長。16位處理器可以有24位地址匯流排。32位處理器也很早就有36位地址匯流排的。以前並口硬碟還是48位地址匯流排。感覺暴露年齡了。別的答案解釋了很多了,我說這麼多廢話就是想強調,實際定址空間真的跟處理器字長沒有必然關係。處理器一直可以用間接定址的方式來使用超過字長的地址空間。另外,其實我們民用64位處理器實際定址範圍還不足64位。
cpu看到的32位地址是virtual address,而flash memory disk用的都是 physical address。當CPU要訪問某一地址的時候,它得到的是virtual address,然後通過page table映射成physical address。通過表項的valid位可以知道這一地址所在的page是不是已經在memory裡面了,如果不在,也就是page fault,則把physical address送去匯流排,通過DMA之類操作的把page從disk取到memory中,然後就可以在memory中去操作對應的那個地址的數據了。整個過程還涉及,TLB miss,memory不夠用,disk上的數據結構,等等。其他任意device都可以映射到address space裡面,然後通過類似上述操作來訪問。
現在絕大部分操作系統使用的虛擬存儲器技術就是分頁,在虛擬存儲器中,程序所產生的地址為虛擬地址,虛擬地址構成了虛擬地址空間,這些虛擬地址通過MMU(內存管理單元)映射為物理地址。 採用分頁機制的系統,虛擬地址空間以頁面為單位進行劃分(一般4K),虛擬地址空間會被劃分成多個等大小的頁面,我們就可以只將用到的虛擬地址空間的頁表寫入內存,而沒有用到的虛擬地址空間的頁表就不寫入,這樣不管硬碟是多大都是可以定址並操作的啦~
32位CPU只能訪問4GB內存是誤讀。好多人都是這麼解釋的,貌似他已經理解了這個問題,實際上他的理解是錯的。
1. 32位CPU有可以支持更大內存。具體可以搜PAE。可能不是所有電腦都支持
2. PAE並非什麼黑科技,16位8086按這種說法還只能訪問64KB內存呢,實際上確是1MB. 因為內存地址是CS左移4位後與IP加起來算的。可以支持20為。32位CPU使用段選擇子來定址段式內存,段選擇字是段描述符表的索引,段描述符實際可以表示的段基址至少是超過32位的。這個可以參考我最近的一個文章,爪機無力不貼鏈接了。
至於硬碟什麼的,道理是一樣的。那麼我們家用32 位CPU的電腦為什麼只能訪問4GB內存呢?實際上是因為你的OS沒有啟用 PAE,也有可能你的電腦不支持PAE。所以你試著搜下「windows xp 啟用 PXE相信會有收穫」。間接訪問,cpu通過發送指令給控制器(系統會為控制器開闢一段地址空間),再由控制器訪問存儲介質。
32位定址只是邏輯地址,不是物理地址。硬碟是通過io埠收發數據,而不是內存。使用內存地址的是內存,顯卡內存等。x86 32位cpu也是可以使用超過4g物理內存的。
笑死了...尋內存地址跟硬碟優盤有毛關係?
定址4GB內存空間的能力是由物理地址(Physical Address)來限制的,這跟cpu32位沒有關係。
CPU在定址時會發出虛擬地址(Virtual Address)(也是32位),然後虛擬地址會經過翻譯變為物理地址,類似於映射。具體翻譯的過程可以是由TLB(Translation Lookaside Buffer)或者Page Table Waking來完成。
如果翻譯出來的物理地址能夠來cache中找到,那就從cache中獲得(這裡cache可以是L1,L2,...,Main Memory);如果找不到,那就得從硬碟,flash這些存儲設備里拿(這個時候就會從硬碟拿一個page去main memory,main memory里拿一個block去cache)。去硬碟拿數據比去cache拿慢很多,但是在這樣的機制下,連續去拿相同的block里word就不會miss。(說的有點多,不知道能不能講明白,尷尬臉。。)
這些都是memory架構相關的知識,有興趣可以去看看計算機架構的書 : )
----------------------------------------
評論里好基友跟我提到了I/O,我又回去看了看別的答案。沒錯,硬碟和flash是可以做I/O外設,我們平常用的移動硬碟,U盤都是外設(嚴格意義上講這些都是flash)。對於訪問存儲外設,目前大多數都是通過USB匯流排協議來交互信息的,這跟CPU的定址能力更沒有什麼關係了。所以32位CPU想訪問多大的移動硬碟就訪問多大,別說4G了,4T都沒問題。
但是萬一題主說的硬碟是老式的用磁頭訪問的硬碟或者是其他用SATA或者PCIe作為匯流排協議的硬碟呢?萬一是eMMC或者UFS標準的移動端的flash呢?所以最開始的答案還有有點用吧。
推薦閱讀:
※python的numpy向量化語句為什麼會比for快?
※能否通過修圖等手段將小解析度的圖片轉變為大解析度?
※USB Type-C 如何決定充電方向?
※一個不加班的程序員有前途嗎?
※次世代遊戲對於PC主機的要求越來越高,遊戲實際上對於主機的要求真的很高嗎?