虚拟地址空间以及编译模式
生活随笔
收集整理的這篇文章主要介紹了
虚拟地址空间以及编译模式
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
原文鏈接
虛擬地址空間以及編譯模式
< 上一頁(yè)虛擬內(nèi)存到底是什么?為什么我們?cè)贑語(yǔ)言中看到的地址是假的? C語(yǔ)言?xún)?nèi)存對(duì)齊,提高尋址效率下一頁(yè) > 所謂虛擬地址空間,就是程序可以使用的虛擬地址的有效范圍。虛擬地址和物理地址的映射關(guān)系由操作系統(tǒng)決定,相應(yīng)地,虛擬地址空間的大小也由操作系統(tǒng)決定,但還會(huì)受到編譯模式的影響。這節(jié)我們先講解CPU,再講解編譯模式,讓大家了解編譯器是如何配合CPU來(lái)提高程序運(yùn)行速度的。
CPU的數(shù)據(jù)處理能力
CPU是計(jì)算機(jī)的核心,決定了計(jì)算機(jī)的數(shù)據(jù)處理能力和尋址能力,也即決定了計(jì)算機(jī)的性能。CPU一次(一個(gè)時(shí)鐘內(nèi))能處理的數(shù)據(jù)的大小由寄存器的位數(shù)和數(shù)據(jù)總線(xiàn)的寬度(也即有多少根數(shù)據(jù)總線(xiàn))決定,我們通常所說(shuō)的多少位的CPU,除了可以理解為寄存器的位數(shù),也可以理解數(shù)據(jù)總線(xiàn)的寬度,通常情況下它們是相等的。 數(shù)據(jù)總線(xiàn)位于主板之上,不在CPU中,也不由CPU決定,嚴(yán)格來(lái)講,這里應(yīng)該說(shuō)CPU能夠支持的數(shù)據(jù)總線(xiàn)的最大根數(shù),也即能夠支持的最大數(shù)據(jù)處理能力,為了表達(dá)方便,本文才使用“CPU的數(shù)據(jù)總線(xiàn)”這一說(shuō)法。 數(shù)據(jù)總線(xiàn)和主頻都是CPU的重要指標(biāo):數(shù)據(jù)總線(xiàn)決定了CPU單次的數(shù)據(jù)處理能力,主頻決定了CPU單位時(shí)間內(nèi)的數(shù)據(jù)處理次數(shù),它們的乘積就是CPU單位時(shí)間內(nèi)的數(shù)據(jù)處理量。我們常常聽(tīng)說(shuō),CPU主頻在計(jì)算機(jī)的發(fā)展過(guò)程中飛速提升,從最初的幾十 KHz,到后來(lái)的幾百 MHz,再到現(xiàn)在的 4GHz,終于因?yàn)楣杈w的物理特性很難再提升,只能向多核方向發(fā)展。在這個(gè)過(guò)程中,CPU的數(shù)據(jù)總線(xiàn)寬度也在成倍增長(zhǎng),從早期的8位、16位,到后來(lái)的32位,現(xiàn)在我們計(jì)算機(jī)大部分都在使用64位CPU。
需要注意的是,數(shù)據(jù)總線(xiàn)和地址總線(xiàn)不是一回事,數(shù)據(jù)總線(xiàn)用于在CPU和內(nèi)存之間傳輸數(shù)據(jù),地址總線(xiàn)用于在內(nèi)存上定位數(shù)據(jù),它們之間沒(méi)有必然的聯(lián)系,寬度并不一定相等。實(shí)際情況是,地址總線(xiàn)的寬度往往隨著數(shù)據(jù)總線(xiàn)的寬度而增長(zhǎng),以訪(fǎng)問(wèn)更大的內(nèi)存。
1) 16位CPU
早期的CPU是16位的,一次能處理 16Bit(2個(gè)字節(jié))的數(shù)據(jù)。這個(gè)時(shí)候計(jì)算機(jī)產(chǎn)業(yè)還處在早期,個(gè)人電腦也沒(méi)有進(jìn)入千家萬(wàn)戶(hù),也沒(méi)有提出虛擬地址的概念,程序還是直接運(yùn)行在物理內(nèi)存上,操作系統(tǒng)對(duì)內(nèi)存的管理非常簡(jiǎn)陋,程序員輕易就能編寫(xiě)一個(gè)惡意程序去修改其他程序的內(nèi)存。學(xué)過(guò)匯編的同學(xué)應(yīng)該知道,典型的16位處理器是 Intel 8086,它的數(shù)據(jù)總線(xiàn)有16根,地址總線(xiàn)有20根,尋址能力為 2^20 = 1MB。
2) 32位CPU
隨著計(jì)算機(jī)產(chǎn)業(yè)的進(jìn)步,出現(xiàn)了32位的CPU,一次能處理 32Bit(4個(gè)字節(jié))的數(shù)據(jù)。這個(gè)時(shí)候就提出了虛擬地址的概念,并被應(yīng)用到CPU和操作系統(tǒng)中,由它們共同完成虛擬地址和物理地址的映射,這使得程序編寫(xiě)更加容易,運(yùn)行更加安全。典型的32位處理器是?Intel 的 80386 和 Intel Pentium 4(奔騰4):80386 的數(shù)據(jù)總線(xiàn)和地址總線(xiàn)寬度都是32位,尋址能力達(dá)4GB;Pentium 4的地址總線(xiàn)寬度是36位,理論尋址能力達(dá)64GB。
3) 64位CPU
現(xiàn)代計(jì)算機(jī)都使用64位的CPU,它們一次能處理64Bit(8個(gè)字節(jié))的數(shù)據(jù)。典型的64位處理器是 Intel 的 Core i3、i5、i7 等,它們的地址總線(xiàn)寬度為 40~50 位左右。64位CPU的出現(xiàn)使個(gè)人電腦再次發(fā)生了質(zhì)的飛躍。實(shí)際支持的物理內(nèi)存
CPU支持的物理內(nèi)存只是理論上的數(shù)據(jù),實(shí)際應(yīng)用中還會(huì)受到操作系統(tǒng)的限制,例如,Win7 ?64位家庭版最大僅支持8GB或16GB的物理內(nèi)存,Win7 64位專(zhuān)業(yè)版或企業(yè)版能夠支持到192GB的物理內(nèi)存。Windows Server 2003 數(shù)據(jù)中心版專(zhuān)為大型企業(yè)或國(guó)家機(jī)構(gòu)而設(shè)計(jì),可以處理海量數(shù)據(jù),分為32位版和64位版,32位版最高支持512GB的物理內(nèi)存,這顯然超出了32位CPU的尋址能力,可以通過(guò)兩次尋址來(lái)實(shí)現(xiàn)。
編譯模式
為了兼容不同的平臺(tái),現(xiàn)代編譯器大都提供兩種編譯模式:32位模式和64位模式。32位編譯模式
在32位模式下,一個(gè)指針或地址占用4個(gè)字節(jié)的內(nèi)存,共有32位,理論上能夠訪(fǎng)問(wèn)的虛擬內(nèi)存空間大小為 2^32 =?0X100000000 Bytes,即4GB,有效虛擬地址范圍是 0 ~ 0XFFFFFFFF。?也就是說(shuō),對(duì)于32位的編譯模式,不管實(shí)際物理內(nèi)存有多大,程序能夠訪(fǎng)問(wèn)的有效虛擬地址空間的范圍就是0 ~ 0XFFFFFFFF,也即虛擬地址空間的大小是 4GB。換句話(huà)說(shuō),程序能夠使用的最大內(nèi)存為 4GB,跟物理內(nèi)存沒(méi)有關(guān)系。
如果程序需要的內(nèi)存大于物理內(nèi)存,或者內(nèi)存中剩余的空間不足以容納當(dāng)前程序,那么操作系統(tǒng)會(huì)將內(nèi)存中暫時(shí)用不到的一部分?jǐn)?shù)據(jù)寫(xiě)入到磁盤(pán),等需要的時(shí)候再讀取回來(lái),這在《載入內(nèi)存,讓程序運(yùn)行起來(lái)》中已經(jīng)講到。而我們的程序只管使用 4GB 的內(nèi)存,不用關(guān)心硬件資源夠不夠。
如果物理內(nèi)存大于 4GB,例如目前很多PC機(jī)都配備了8GB的內(nèi)存,那么程序也無(wú)能為力,它只能夠使用其中的 4GB。
64位編譯模式
在64位編譯模式下,一個(gè)指針或地址占用8個(gè)字節(jié)的內(nèi)存,共有64位,理論上能夠訪(fǎng)問(wèn)的虛擬內(nèi)存空間大小為 2^64。這是一個(gè)很大的值,幾乎是無(wú)限的,就目前的技術(shù)來(lái)講,不但物理內(nèi)存不可能達(dá)到這么大,CPU的尋址能力也沒(méi)有這么大,實(shí)現(xiàn)64位長(zhǎng)的虛擬地址只會(huì)增加系統(tǒng)的復(fù)雜度和地址轉(zhuǎn)換的成本,帶不來(lái)任何好處,所以 Windows 和 Linux 都對(duì)虛擬地址進(jìn)行了限制,僅使用虛擬地址的低48位(6個(gè)字節(jié)),總的虛擬地址空間大小為 2^48 = 256TB。需要注意的是:
- 32位的操作系統(tǒng)只能運(yùn)行32位的程序(也即以32位模式編譯的程序),64位操作系統(tǒng)可以同時(shí)運(yùn)行32位的程序(為了向前兼容,保留已有的大量的32位應(yīng)用程序)和64位的程序(也即以64位模式編譯的程序)。
- 64位的CPU運(yùn)行64位的程序才能發(fā)揮它的最大性能,運(yùn)行32位的程序會(huì)白白浪費(fèi)一部分資源。
目前計(jì)算機(jī)可以說(shuō)已經(jīng)進(jìn)入了64位的時(shí)代,之所以還要提供32位編譯模式,是為了兼容一些老的硬件平臺(tái)和操作系統(tǒng),或者某些場(chǎng)合下32位的環(huán)境已經(jīng)足夠,使用64位環(huán)境會(huì)增大成本,例如嵌入式系統(tǒng)、單片機(jī)、工控等。 這里所說(shuō)的32位環(huán)境是指:32位的CPU + 32位的操作系統(tǒng) + 32位的程序。 另外需要說(shuō)明的是,32位環(huán)境擁有非常經(jīng)典的設(shè)計(jì),易于理解,適合教學(xué),現(xiàn)有的很多資料都是以32位環(huán)境為基礎(chǔ)進(jìn)行講解的。本教程也是如此,除非特別指明,否則都是針對(duì)32位環(huán)境。相比于32位環(huán)境,64位環(huán)境的設(shè)計(jì)思路并沒(méi)有發(fā)生質(zhì)的變化,理解了32環(huán)境很容易向64位環(huán)境遷移。
開(kāi)啟64位編譯模式
以 VS2010 為例,創(chuàng)建工程后默認(rèn)是32位的,如下圖所示:“Win32”表示32位編譯模式。如果要以64位的方式編譯,就需要新增編譯模式,如下圖所示:
選擇“配置管理器”,彈出如下的對(duì)話(huà)框:
在“活動(dòng)解決方案平臺(tái)”下選擇“新建”,彈出下面的對(duì)話(huà)框:
在下拉菜單中選擇“x64”,即可新增64位編譯模式。現(xiàn)在,我們就可以在兩種編譯模式之間進(jìn)行切換了:
將下面的代碼復(fù)制到源文件中: 復(fù)制純文本復(fù)制
}
在 Win32 編譯模式下的結(jié)果:
0XB715C, 4
在 x64 編譯模式下的結(jié)果:
0X3FF39740, 8
關(guān)注微信公眾號(hào)「站長(zhǎng)嚴(yán)長(zhǎng)生」,在手機(jī)上閱讀所有教程,隨時(shí)隨地都能學(xué)習(xí)。本公眾號(hào)由C語(yǔ)言中文網(wǎng)站長(zhǎng)運(yùn)營(yíng),每日更新,堅(jiān)持原創(chuàng),敢說(shuō)真話(huà),凡事有態(tài)度。
微信掃描二維碼關(guān)注公眾號(hào)
優(yōu)秀文章
- malloc和free函數(shù)使用注意事項(xiàng),C語(yǔ)言malloc和free使用詳解
- MySQL TAN函數(shù):求正切值
- Shell let命令:對(duì)整數(shù)進(jìn)行數(shù)學(xué)運(yùn)算
- JSP PageContext.getPage()方法:返回當(dāng)前page對(duì)象
- JSP JSTL <x:set>標(biāo)簽:保存XML節(jié)點(diǎn)
- 營(yíng)銷(xiāo)型網(wǎng)站的建設(shè)流程(非常詳細(xì))
- Python lambda函數(shù)(匿名函數(shù))的定義
- Redis SDIFFSTORE命令
- <sql:setDataSource>標(biāo)簽
- PHP JSON的解析和創(chuàng)建
總結(jié)
以上是生活随笔為你收集整理的虚拟地址空间以及编译模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 用fpda 写一个risc-v
- 下一篇: Linux下C语言程序的内存布局(内存模