❶ 編譯器的組成及各部分的功能及作用
1. 詞法分析 詞法分析器根據詞法規則識別出源程序中的各個記號(token),每個記號代表一類單詞(lexeme)。源程序中常見的記號可以歸為幾大類:關鍵字、標識符、字面量和特殊符號。詞法分析器的輸入是源程序,輸出是識別的記號流。詞法分析器的任務是把源文件的字元流轉換成記號流。本質上它查看連續的字元然後把它們識別為「單詞」。 2. 語法分析 語法分析器根據語法規則識別出記號流中的結構(短語、句子),並構造一棵能夠正確反映該結構的語法樹。 3. 語義分析 語義分析器根據語義規則對語法樹中的語法單元進行靜態語義檢查,如果類型檢查和轉換等,其目的在於保證語法正確的結構在語義上也是合法的。 4. 中間代碼生成 中間代碼生成器根據語義分析器的輸出生成中間代碼。中間代碼可以有若干種形式,它們的共同特徵是與具體機器無關。最常用的一種中間代碼是三地址碼,它的一種實現方式是四元式。三地址碼的優點是便於閱讀、便於優化。 5. 中間代碼優化 優化是編譯器的一個重要組成部分,由於編譯器將源程序翻譯成中間代碼的工作是機械的、按固定模式進行的,因此,生成的中間代碼往往在時間和空間上有很大浪費。當需要生成高效目標代碼時,就必須進行優化。 6. 目標代碼生成 目標代碼生成是編譯器的最後一個階段。在生成目標代碼時要考慮以下幾個問題:計算機的系統結構、指令系統、寄存器的分配以及內存的組織等。編譯器生成的目標程序代碼可以有多種形式:匯編語言、可重定位二進制代碼、內存形式。 7 符號表管理 符號表的作用是記錄源程序中符號的必要信息,並加以合理組織,從而在編譯器的各個階段能對它們進行快速、准確的查找和操作。符號表中的某些內容甚至要保留到程序的運行階段。 8 出錯處理用戶編寫的源程序中往往會有一些錯誤,可分為靜態錯誤和動態錯誤兩類。所謂動態錯誤,是指源程序中的邏輯錯誤,它們發生在程序運行的時候,也被稱作動態語義錯誤,如變數取值為零時作為除數,數組元素引用時下標出界等。靜態錯誤又可分為語法錯誤和靜態語義錯誤。語法錯誤是指有關語言結構上的錯誤,如單詞拼寫錯、表達式中缺少操作數、begin和end不匹配等。靜態語義錯誤是指分析源程序時可以發現的語言意義上的錯誤,如加法的兩個操作數中一個是整型變數名,而另一個是數組名等。
❷ visual studio 編譯器的堆空間不足問題的解決(cmake版本)
我們有個自動編譯游戲引擎的腳本,這個腳本時間用久了,總是會報如下的錯誤:
fatal error C1060: 編譯器的堆空間不足
每次出現這種錯誤,總是要請人重啟機器,重新配置,很耽誤時間和精力。
所以本人就在努力尋找一個徹底的解決辦法。
想直接要解決方法的朋友可以跳過接下來的兩節。
簡單網上搜一下,就能搜到參考文獻1。
如果你的c++工程不用cmake,參考文獻1的方法足以滿足你的需求。
但是我們工程比較大,肯定是要用cmake的,所以我就開始嘗試各種方法: 通過改工程的cmake文件的方式來讓cmake生成的vcxproj工程文件中包含PreferredToolArchitecture屬性。
網上找了好久,試了不少辦法,還是沒用。
發現最終解決方案也是個很有趣的過程,值得記錄。
首先我看見PreferredToolArchitecture父節點是PropertyGroup,而PropertyGroup下面有Platform屬性,PreferredToolArchitecture和Platform是兄弟屬性。
我們的Platform用x64還是win32,都是在cmake命令行里指定的。
所以我就大膽猜測,PreferredToolArchitecture這個屬性如果可以通過cmake設置的話,大概率也是在cmake的命令行中設置!
接著,就是小心求證的過程,先執行: cmake --help
通過閱讀幫助文檔,輔以簡單的排除法,我覺得toolset-name這個屬性很可能是我要的,於是谷歌: cmake toolset name
從而找到了文檔2,在文檔2中發現了host=x64這個東西,但是我還不知道怎麼用!於是繼續搜索:cmake host=x64
找到了文檔3,然後修改我們的編譯腳本,加入這個編譯選項,重新cmake,果然,出現了vcxproj文件中看到了PreferredToolArchitecture x64屬性!
感覺成功了90%,編譯工程,打開任務管理器,觀察進程名稱,發現c++編譯器都是64位的,遂大功告成。
問題的本質就是windows操作系統visual studio的默認cpp編譯器是32位的,所以最大內存是4G,就容易導致編譯器內存不足。
有問題的cmake指令如下:
使用64位的cpp編譯器的解決方法如下:
注意: cmake的GUI並沒有-T host的選擇,當然最新版的GUI可能也會加這個。。
還有另一種方法,添加環境變數: set PreferredToolArchitecture=x64
雖然用了64位的cpp編譯器,過了一段時間,還是報堆空間不足的問題。
據觀察,物理內存佔用率100%,所以考慮利用空閑的磁碟空間,增大機器的虛擬內存。
win10如何設置虛擬內存的大小: https://jingyan..com/article/2fb0ba4041d14c00f3ec5f4e.html
物理內存只有32G,以前的虛擬內存是6G,我利用空閑磁碟,增大虛擬內存到100G!
❸ 編譯軟體要多核CPU還是高主頻的啊,32個g內存128g硬碟夠嗎
編譯軟體需要多核處理器,32GB內存、128GB固態硬碟完全夠用。
❹ 編譯時分配內存和運行時分配內存
編譯其實只是一個掃描過程,進行詞法語法檢查,代碼優化而已,編譯程序越好,程序運行的時候越高效。
我想你說的「編譯時分配內存」是指「編譯時賦初值」,它只是形成一個文本,檢查無錯誤,並沒有分配內存空間。
當你運行時,系統才把程序導入內存。一個進程(即運行中的程序)在主要包括以下五個分區:
棧、堆、bss、data、code
代碼(編譯後的二進制代碼)放在code區,代碼中生成的各種變數、常量按不同類型分別存放在其它四個區。系統依照代碼順序執行,然後依照代碼方案改變或調用數據,這就是一個程序的運行過程。
❺ vs編譯內存過多
vs編譯內存過多?
編譯器佔用內此灶存一般是比較大的森豎扮,如果顯示佔用內存特別大,時間特別長,有可能是纖昌程序,本身有問題,導致編譯過程無法完成
❻ 「Keil C51」下如何讓編譯器優先使用片內「RAM」
C51內存拿歲者結構深度剖析x0dx0a在編寫應用程序時,定義一個變數,一個數組,或是說一個固定表格,到底存儲在什麼地方;當定義變數大小超過MCU的內存范圍時怎麼辦;如何控制變數定義不超過存儲范圍;以及如何定義變數才能使得變數訪問速度最快,寫出的程序運行效率最高。以下將一一解答。x0dx0ax0dx0a1 六類關鍵字(六類存儲類型)x0dx0adata idata xdata pdata code bdatax0dx0ax0dx0a code: code memory (程序存儲器也即只讀存儲器)用來保存常量或是程序。code memory 採用16位地址線編碼,可以是在片內,或是片外,大小被限制在64KBx0dx0a 作用:定義常量,如八段數碼表或是編程使用的常,在定義時加上code 或明確指明定義的常量保存到code memory(只讀)x0dx0a 使用方法:x0dx0a char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};x0dx0a 此關鍵字的使用方法等同於constx0dx0ax0dx0adata data memory (數據存儲區)只能用於聲明變數,不能用來聲明函數,該區域位於片內,採用8位地址線編碼,具有最快的存儲速度,但是數量被限制在128byte或更少。x0dx0a 使用方法:x0dx0a unsigned char data fast_variable=0;x0dx0ax0dx0a idata idata memory(數據存儲區)只能用於聲明變數,不能用來聲明函數. 該區域位於片內,採用8位地址線編碼,內存大小被限制在256byte或更少。該區域消薯的低地址區與data memory地址一致;高地址區域是52系列在51系列基礎上擴展的並與特殊功能寄存器具有相同地址編碼的區域。即:data memory是idata memory的一個子集。x0dx0a x0dx0a xdata xdata memory 只能用於聲明變數,不能用來聲明函數,該區域位於MCUx0dx0a 外部,採用16位地址線進行編碼,存儲大小被限制在64KB以內。x0dx0a 使用方法:x0dx0a unsigned char xdata count=0;x0dx0ax0dx0apdata pdata memory 只能用於聲明變數,不能用雀衫來聲明函數,該區域位於MCU外部,採用8位地址線進行編碼。存儲大小限制在256byte. 是xdata memory的低256byte。為其子集。x0dx0a 使用方法x0dx0a unsigned char pdata count=0;x0dx0ax0dx0a bdata bdata memory 只能用於聲明變數,不能用來聲明函數。該區域位於8051內部位數據地址。定義的量保存在內部位地址空間,可用位指令直接讀寫。x0dx0a 使用方法:x0dx0a unsigned char bdata varab=0x0dx0ax0dx0a 註:有些資料講,定義字元型變數時,在預設unsigned 時,字元型變數,默認為無符號,與標准C不同,但我在Keil uVision3中測試的時候發現並非如此。在預設的情況下默認為有符號。或許在以前的編譯器是默認為無符號。所以看到有的資料上面這樣講的時候,要注意一下,不同的編譯器或許不同。所以我們在寫程序的時候,還是乖乖的把unsigned signed 加上,咱也別偷這個懶。x0dx0a 2函數的參數和局部變數的存儲模式x0dx0a C51 編譯器允許採用三種存儲器模式:SMALL,COMPACT 和LARGE。一個函數的存儲器模式確定了函數的參數的局部變數在內存中的地址空間。處於SMALL模式下的函數參數和局部變數位於8051單片機內部RAM中,處於COMPACT和LARGE模式下的函數參數和局部變數則使用單片機外部RAM。在定義一個函數時可以明確指定該函數的存儲器模式。方法是在形參表列的後面加上一存儲模式。x0dx0a x0dx0a 示例如下:x0dx0a #pragma large //此預編譯必須放在所有頭文前面x0dx0a int func0(char x,y) small;x0dx0a char func1(int x) large;x0dx0a int func2(char x);x0dx0a 註:x0dx0a 上面例子在第一行用了一個預編譯命令#pragma 它的意思是告訴c51編譯器在對程序進行編譯時,按該預編譯命令後面給出的編譯控制指令LARGE進行編譯,即本常式序編譯時的默認存儲模式為LARGE.隨後定義了三個函數,第一個定義為SMALL存儲模式,第二個函數定義為LARGE第三個函數未指定,在用C51進行編譯時,只有最後一個函數按LARGE存儲器模式處理,其它則分別按它們各自指定的存儲器模式處理。x0dx0a 本例說明,C51編譯器允許採用所謂的存儲器混合模式,即允許在一個程序中將一些函數使用一種存儲模式,而其它一些則按另一種存儲器模式,採用存儲器混合模式編程,可以充分利用8051系列單片機中有限的存儲器空間,同時還可以加快程序的執行速度。x0dx0ax0dx0a3絕對地址訪問 absacc.h(相當重要)x0dx0ax0dx0a#define CBYTE ((unsigned char volatile code *) 0)x0dx0a#define DBYTE ((unsigned char volatile data *) 0)x0dx0a#define PBYTE ((unsigned char volatile pdata *) 0)x0dx0a#define XBYTE ((unsigned char volatile xdata *) 0)x0dx0a 功能:CBYTE 定址 CODE區x0dx0a DBYTE 定址 DATA區x0dx0a PBYTE 定址 XDATA(低256)區x0dx0a XBYTE 定址 XDATA區x0dx0a 例: 如下指令在對外部存儲器區域訪問地址0x1000x0dx0a xvar=XBYTE[0x1000];x0dx0a XBYTE[0x1000]=20;x0dx0ax0dx0a#define CWORD ((unsigned int volatile code *) 0)x0dx0a#define DWORD ((unsigned int volatile data *) 0)x0dx0a#define PWORD ((unsigned int volatile pdata *) 0)x0dx0a#define XWORD ((unsigned int volatile xdata *) 0)x0dx0ax0dx0a 功能:與前面的一個宏相似,只是它們指定的數據類型為unsigned int .。x0dx0a 通過靈活運用不同的數據類型,所有的8051地址空間都是可以進行訪問。x0dx0a 如x0dx0aDWORD[0x0004]=0x12F8;x0dx0a即內部數據存儲器中(0x08)=0x12; (0x09)=0xF8x0dx0ax0dx0a註:用以上八個函數,可以完成對單片機內部任意ROM和RAM進行訪問,非常方便。還有一種方法,那就是用指鍾,後面會對C51的指針有詳細的介紹。x0dx0ax0dx0a4寄存器變數(register)x0dx0a 為了提高程序的執行效率,C語言允許將一些頻率最高的那些變數,定義為能夠直接使用硬體寄存器的所謂的寄存器變數。定義一個變數時,在變數類型名前冠以「register」 即將該變數定義成為了寄存器變數。寄存器變數可以認為是一自動變數的一種。有效作用范圍也自動變數相同。由於計算機寄存器中寄存器是有限的。不能將所有變數都定義成為寄存器變數,通常在程序中定義寄存器變數時,只是給編譯器一個建議,該變數是否真正成為寄存器變數,要由編譯器根據實際情況來確定。另一方面,C51編譯器能夠識別程序中使用頻率最高的變數,在可能的情況下,即使程序中並未將該變數定義為寄存器變數,編譯器也會自動將其作為寄存器變數處理。被定義的變數是否真正能成為寄存器變數,最終是由編譯器決定的。x0dx0ax0dx0a5內存訪問雜談x0dx0a 1指鍾x0dx0a指鍾本身是一個變數,其中存放的內容是變數的地址,也即特定的數據。8051的地址是16位的,所以指針變數本身佔用兩個存儲單元。指針的說明與變數的說明類似,僅在指針名前加上「*」即可。x0dx0a 如 int *int_point; 聲明一個整型指針x0dx0a char *char_point; 聲明一個字元型指針x0dx0a 利用指針可以間接存取變數。實現這一點要用到兩個特殊運算符x0dx0a & 取變數地址x0dx0a * 取指針指向單元的數據x0dx0ax0dx0a示例一:x0dx0aint a,b;x0dx0a int *int_point; //定義一個指向整型變數的指針x0dx0a a=15;x0dx0a int_point=&a; //int_point指向 ax0dx0a *int_point=5; //給int_point指向的變數a 賦值5 等同於a=5; x0dx0a示例二:x0dx0a char i,table[6],*char_point;x0dx0a char_point=table;x0dx0a for(i=0;i<6;i++)x0dx0a {x0dx0a char_point=i;x0dx0a char_point++;x0dx0a}x0dx0a註:x0dx0a 指針可以進行運算,它可以與整數進行加減運算(移動指針)。但要注意,移動指針後,其地址的增減量是隨指針類型而異的,如,浮點指針進行自增後,其內部將在原有的基礎上加4,而字元指針當進生自增的時候,其內容將加1。原因是浮點數,佔4個內存單元,而字元佔一個位元組。x0dx0ax0dx0a宏晶科技最新一代STC12C5A360S2系列,每一個單片機出廠時都有全球唯一身份證號碼(ID號),用戶可以在單片機上電後讀取內部RAM單元F1H~F7H的數值,來獲取此單片機的唯一身份證號碼。使用MOV @Ri 指令來讀取。下面介紹C51 獲取方法:x0dx0a char id[7]={0};x0dx0a char i;x0dx0a char idata *point;x0dx0a for(i=0;i<7;i++)x0dx0a {x0dx0a id[i]=*point;x0dx0a point++;x0dx0a}x0dx0a x0dx0a(此處只是對指針做一個小的介紹,達到訪問內部任何空間的方式,後述有對指針使用的詳細介紹)x0dx0a2對SFR,RAM ,ROM的直接存取x0dx0aC51提供了一組可以直接對其操作的擴展函數x0dx0a若源程序中,用#include包含頭文件,io51.h 後,就可以在擴展函數中使用特殊功能寄存器的地址名,以增強程序的可讀性:x0dx0ax0dx0a 注 此方法對SFR,RAM,ROM的直接存取不建議使用.因為,淡io51.h這個頭文件在KEIL中無法打開,可用指針,或是採用absacc.h頭文件,
❼ 編譯器為數組開辟的內存空間是
編譯器為數派圓組開辟的內存空間是未知的。
1、編譯器就是將一早羨褲種語言(通常為高級語言)翻譯為另一種語言(通常為低級語言)的程序。一個現代編譯器的主要工作流程:源代碼、預處理器、編譯器、目標代碼、鏈接器、可執行程序。
2、編譯器可以生成用來在與編譯器本身所在的計算機和操作系統(平台)相同的環境下運行的目標代碼,這種編譯器又陸簡叫做本地編譯器。
❽ 「編譯器」如何設置內存區域
不是.
編譯好後的exe文件並非只有代碼部分,還有其他的部分如數據部分以及其他.其中包括諸如內存如何分配,堆棧如何處理等等的描述.而這些描述就是編譯器寫進exe文件里的.
如果想知道的詳細些,可以簡單的看一下關於PE結構的描述~~
❾ c++ int和long int占幾個位元組
在C/C++語言中,int和long int的所佔的位元組數與編譯器有關。
不過現在常用的編譯器多認為int和long int相同,均為4位元組,short為2位元組,char為1位元組。
如果只輸入int,它是可以包含以上三種形式。
不同的語言不太一樣,例如在Pascal中integer為2位元組,byte為1位元組,而longint為4位元組。
建議您最好參考您桐襲的編譯器的具體幫助,以得到更准確的信息。
使用前最好sizeof(int) 看看當前編譯器如何定義的。
依據程序編譯器的不同,int定義的位元組數不同。(數據佔用內存儲器的大小不同)
常用的單片機編譯器,如KEIL下,51類單片機的C語言中,int代表2個位元組(16位);如果是32位RAM處理器的C語言中,則int代表4個位元組(32位)
PIC單片機的PICC中8位系列單片機的C語言里int表示16位。
而不少PC端軟體的編譯器則會根據操作系統或處理器(如64位XP)把int定義為8位元組(64位)
所以在多平台上編程的人員需要在使用時注意。
如需定義16位數,可使用short(短、短整數類型)定義。
(9)編譯器常用內存擴展閱讀:
在一般的電腦中,int佔用4位元組,32比特,數據范圍為-2147483648~2147483647[-2^31~2^31-1]。
在之前的微型機中,int佔用2位元組,16比特,數據范圍為卜輪消-32768~32767[-2^15~2^15-1]。
使用printf輸出int佔用位元組數量:
除了int類型之外,還有short、long、long long類型可以表示整數。
unsigned int 表示無符號整數,數據范圍為[0~2^32-1]。
參考鏈接:INT(數據類型)_百型知度網路
❿ (vc6.0編譯器)這個軟體的內存有多大呢
128M的內存就可以了,那個是10年以前的軟體.