程序編譯虛擬地址
1. 如何將虛擬地址轉化成pfn,即頁幀號麻煩告訴我
用戶程序中的虛擬地址,靜態的是編譯時就定好的,動態的(如malloc),是通過內核的頁式內存管理在vma中定的,需要找到進程的task_struct中的頁表然後一級級的翻譯得到物理地址。
實際編譯時定的地址叫做邏輯地址,這個邏輯地址是需要段式管理來翻譯的,即段基址加段內偏移,由於linux中的這個段基址就是0,所以邏輯地址就直接對應了虛擬地址了。
這樣得到物理地址以後,首先將十六進制的低三位與成0,這樣做是得到頁的物理地址,這里指4K頁的情況,然後通過頁的物理地址減去mem_map的第一個元素的地址就得到了此頁在mem_map數組中的下標(此處注意指針相減不是指針表示的地址相減,而是兩者之間指針所表示元素類型的個數),此下標即為pfn,知道了在數組中的下標就可以得到struct page結構體了,就可以知道page的所有情況了。
2. 我學C語言指針內存中的地址是什麼意思
在每次我們聲明一個變數時,系統會自動給變數在內存中分配一個地址,而指針如果只是聲明它沒有為它賦值的話,它就是個空指針,不指向任何的內存地址。 例如: int x =5,*p; p = &x ;
上面這句話, 聲明了一個x 變數和一個指針p, 並且我們把變數x 的地址賦給了指針p,這樣指針p 就指向了變數x的地址,*p 指的就是 它指向的地址上的值,也就是說 *p =5 ; 也就是說指針是用來存儲地址的東西。
3. 在C語言程序中如何區分傳遞參數是虛擬地址還是物理地址
只能通過取值范圍來判定。
一般情況下,如果是大於虛擬內存的地址,就是物理地址。
4. LinuxOS,Linux首先使用的是物理內存,然後使用虛擬內存。為什麼編譯程序的時候列印的是虛擬內存的地址
第一層理解
1. 每個進程都有自己獨立的4G內存空間,各個進程的內存空間具有類似的結構
2. 一個新進程建立的時候,將會建立起自己的內存空間,此進程的數據,代碼等從磁碟拷貝到自己的進程空間,哪些數據在哪裡,都由進程式控制製表中的task_struct記錄,task_struct中記錄中一條鏈表,記錄中內存空間的分配情況,哪些地址有數據,哪些地址無數據,哪些可讀,哪些可寫,都可以通過這個鏈表記錄
3. 每個進程已經分配的內存空間,都與對應的磁碟空間映射
5. 既然計算機中程序和數據都有自己的物理地址,為何又要引入虛擬地址虛擬地址存在的必要性是什麼
你可以認為這兩者的區別就像機器語言和高級編程語言的區別,物理地址難記,不好管理,交給底層程序自己管理,但要進行讀寫必須對應物理地址。邏輯地址容易記,方便管理進行編程,降低了你對地址的管理難度。
6. 調試代碼的時候顯示的地址是物理地址還是虛擬地址
虛擬地址,是程序的地址,程序在操作系統中有入口地址,而程序中的地址則是入口地址的相對位置
。
物理地址就是,機器內主存的地址,包括RAM和ROM
虛擬地址就是,cpu支持的內存空間遠遠大於機器主存的大小,這些多出來的空間對於程序來說是可以用的,這個時候的所有地址都稱為虛擬地址。
這個要學操作系統才能理解,推薦看
人民郵電出版社
7. 什麼是虛擬地址
虛擬地址是Windows程序時運行在386保護模式下,這樣程序訪問存儲器所使用的邏輯地址稱為虛擬地址,與實地址模式下的分段地址類似,虛擬地址也可以寫為「段:偏移量」的形式,這里的段是指段選擇器。
8. C++,輸出變數的地址,那個地址是程序虛擬地址空間的地址還是實際的物理地址
源代碼在編譯時虛擬地址是已經確定好的,而程序中列印的地址是虛擬地址,所以兩次列印的是一樣的!
9. 請問下虛擬地址的問題
那個賬號提交有問題,換個賬號回答你。
首先,虛擬地址和邏輯地址是一樣的概念。
linux分段的時候把不同進程映射到不同的線性地址,是在linux 0.11內核代碼中出現的。之所以這樣是因為,0.11版本雖然開啟了分頁機制,但是所有進程共享了同一個頁目錄,所以進程們只能分配其中一段使用。這時候每個進程的線性地址空間沒有那麼大(沒有4GB)。
後來linux內核為了增大單個進程的線性地址空間,就不再共享頁目錄,也就是每個進程有獨立的頁目錄,此時進程的段地址基址就可以設置為0,而不會再相互干涉。
每個進程基址都從0開始,並且都擁有4GB的線性地址空間,這就相當於沒有使用分段機制,實際上分段和分頁都採用了。
10. 操作系統課程設計物理地址和虛擬地址的聯系及區別
CPU通過地址來訪問內存中的單元,地址有虛擬地址和物理地址之分,如果CPU沒有MMU(Memory Management Unit,內存管理單元),或者有MMU但沒有啟用,CPU核在取指令或訪問內存時發出的地址將直接傳到CPU晶元的外部地址引腳上,直接被內存晶元(以下稱為物理內存,以便與虛擬內存區分)接收,這稱為物理地址(Physical Address,以下簡稱PA),如下圖所示。
MMU將虛擬地址映射到物理地址是以頁(Page)為單位的,對於32位CPU通常一頁為4K。例如,虛擬地址0xb700 1000~0xb700 1fff是一個頁,可能被MMU映射到物理地址0x2000~0x2fff,物理內存中的一個物理頁面也稱為一個頁框(Page Frame)。
物理地址(physical address)
用於內存晶元級的單元定址,與處理器和CPU連接的地址匯流排相對應。
——這個概念應該是這幾個概念中最好理解的一個,但是值得一提的是,雖然可以直接把物理地址理解成插在機器上那根內存本身,把內存看成一個從0位元組一直到最大空量逐位元組的編號的大數組,然後把這個數組叫做物理地址,但是事實上,這只是一個硬體提供給軟體的抽像,內存的定址方式並不是這樣。所以,說它是「與地址匯流排相對應」,是更貼切一些,不過拋開對物理內存定址方式的考慮,直接把物理地址與物理的內存一一對應,也是可以接受的。也許錯誤的理解更利於形而上的抽像。
虛擬內存(virtual memory)
這是對整個內存(不要與機器上插那條對上號)的抽像描述。它是相對於物理內存來講的,可以直接理解成「不直實的」,「假的」內存,例如,一個0x08000000內存地址,它並不對就物理地址上那個大數組中0x08000000 - 1那個地址元素;
之所以是這樣,是因為現代操作系統都提供了一種內存管理的抽像,即虛擬內存(virtual memory)。進程使用虛擬內存中的地址,由操作系統協助相關硬體,把它「轉換」成真正的物理地址。這個「轉換」,是所有問題討論的關鍵。
有了這樣的抽像,一個程序,就可以使用比真實物理地址大得多的地址空間。(拆東牆,補西牆,銀行也是這樣子做的),甚至多個進程可以使用相同的地址。不奇怪,因為轉換後的物理地址並非相同的。
——可以把連接後的程序反編譯看一下,發現連接器已經為程序分配了一個地址,例如,要調用某個函數A,代碼不是call A,而是call 0x0811111111 ,也就是說,函數A的地址已經被定下來了。沒有這樣的「轉換」,沒有虛擬地址的概念,這樣做是根本行不通的。
打住了,這個問題再說下去,就收不住了。
邏輯地址(logical address)
Intel為了兼容,將遠古時代的段式內存管理方式保留了下來。邏輯地址指的是機器語言指令中,用來指定一個操作數或者是一條指令的地址。以上例,我們說的連接器為A分配的0x08111111這個地址就是邏輯地址。
——不過不好意思,這樣說,好像又違背了Intel中段式管理中,對邏輯地址要求,「一個邏輯地址,是由一個段標識符加上一個指定段內相對地址的偏移量,表示為 [段標識符:段內偏移量],也就是說,上例中那個0x08111111,應該表示為[A的代碼段標識符: 0x08111111],這樣,才完整一些」
線性地址(linear address)或也叫虛擬地址(virtual address)
跟邏輯地址類似,它也是一個不真實的地址,如果邏輯地址是對應的硬體平台段式管理轉換前地址的話,那麼線性地址則對應了硬體頁式內存的轉換前地址。