c0編譯器怎麼用
A. c語言如何把一個字元串格式的二進制數轉化為整數型的十進制數
首先要說,在計算機裡面不存在十進制數。我們看到的輸出的十進制數,其實是C編譯器把真正的二進制數的數值以十進制形式顯示在屏幕上。如果說計算機裡面有十進制數的話,那麼BCD數可以算是一種形式的十進制數。
而題目中的字元串格式的二進制數,也就是一串的'0','1'字元;轉化為整數型其實就是求得其實際數值,最後以十進制形式輸出。
#include <stdio.h>
int main()
{
long int m;
char c0[50],*c ;
while(scanf("%s",c0)!=EOF){
m = 0;c=c0;
while(*c)
m += (m + *(c++)-'0');
printf("%d\n",m);
}
return 0;
}
B. C語言這么厲害,它自身又是用什麼語言寫的編寫過程被稱為自舉
來自一個小白的提問: 「C語言本身用什麼語言寫的?」
換個角度來問,其實是:C語言在運行之前,得編譯才行,那C語言的編譯器從哪裡來?用什麼語言來寫的?如果是用C語言本身來寫的,到底是先有蛋還是先有雞?
我們假設世界上不存在任何編譯器, 先從機器語言說起,看看怎麼辦。
機器語言可以直接被CPU執行,不需要編譯器。
然後是匯編語言, 匯編語言雖然只是機器語言的助記符,但是也需要編譯成機器語言才能執行,沒辦法只能用機器語言來寫這第一個編譯器了(以後就不用了)。
匯編語言的問題解決了,就往前邁進了一大步,這時候就可以用匯編語言去寫C語言的編譯器,我們說這是C編譯器的老祖宗。
有了這個老祖宗,就可以編譯任意的C語言程序了,那是不是可以用C語言本身寫一個編譯器?只要用老祖宗編譯一下就可以了。
OK, 這么一層層上來,終於得到了一個用C語言寫的編譯器, 真是夠麻煩的。
到這個時候,之前那個匯編寫的C語言編譯器就可以拋棄了。
當然,如果在C語言之前,已經出現了別的高級語言,例如Pascal,那就可以用Pascal來寫一個C語言的編譯器。
第一個Pascal的編譯器據說使用Fortran寫的。而作為第一個高級語言的Fortran,它的編譯器應該是匯編語言寫的。
關於編譯器,這里邊有個有趣的傳說:
傳說Unix 發明人之一的 Ken Thompson在貝爾實驗室,大搖大擺的走到任何一台Unix機器前,輸入自己的用戶名和密碼,就能以root的方式登錄!
貝爾實驗室人才濟濟,另外一些大牛發誓要把這個漏洞找出來,他們通讀了Unix的C源碼,終於找到了登錄的後門, 清理後門以後編譯Unix , 運行, 可是Thompson 還是能夠登錄進去。
有人覺得可能是編譯器中有問題,在編譯Unix的時候植入了後門, 於是他們又用C語言重新寫了一個編譯器,用新的編譯器再次編譯了Unix, 這下總算天下太平了吧。
可是仍然不管用, Thompson 依然可以用root登錄,真是讓人崩潰!
後來Thompson 本人解開了秘密,是第一個C 語言編譯器有問題, 這個編譯器在編譯Unix源碼的時候,當然會植入後門, 這還不夠,更牛的是,如果你用C 語言寫了一個新編譯器,肯定也需要編譯成二進制代碼啊,用什麼來編譯,只有用Thompson寫的那第一個編譯器來編譯,好了, 你寫的這個編譯器就會被污染了,你的編譯器再去編譯Unix , 也會植入後門 :-)
說到這里我就想起了幾年前的XcodeGhost 事件,簡單來說就是在Xcode(非官方渠道下載的)中植入了木馬,這樣XCode編譯出的ios app都被污染了,這些app就可以被黑客利用做非法之事。
雖然這個XCodeGhost和Thompson的後面相比差得遠,但是提醒我們,下載軟體的時候要走正規渠道,從官方網站下載,認准網站的HTTPS標准,甚至可以驗證一下checksum。
可能有人問:我用匯編寫一段Hello World都很麻煩,居然有人可以用它寫復雜的編譯器?這可能嗎?
當然可能,在開發第一代Unix的時候,連C語言都沒有, Ken Thompson 和 Dennis Ritchie 可是用匯編一行行把Unix敲出來的。 WPS第一版是求伯君用匯編寫出來的, Turbo Pascal 的編譯器也是Anders 用匯編寫出來的,大神們的能力不是普通人能想像得到的。
對於編譯器來說,還可以採用「滾雪球」的方式來開發:
還是以C語言為例,第一個版本可以先選擇C語言的一個子集,例如只支持基本的數據類型,流程式控制制語句,函數調用...... 我們把這個子集稱為C0。
然後用匯編語言寫個編譯器,只搞定這個語言的子集C0,這樣寫起來就容易不少。
C0這個語言可以工作了,然後我們擴展這個子集,例如添加struct,指針...... ,把新的語言稱為C1。
那C1這個語言的編譯器由誰來寫? 自然是C0。
等到C1可以工作了,再次擴展語言特性,用C1寫編譯器,得到C2。
然後是C3, C4...... 最後得到完整的C語言。
這個過程被稱為bootstraping , 中文叫做自舉。
對於熱愛編程的人來說,有一群一起學習一起解答的小夥伴很重要!
這里有一個 C/C++編程學習交流俱樂部 (群),私信我【01】進入!
還有編程學習文件(源碼,零基礎教程,項目實戰教學視頻),歡迎初學者和正在進階中的小夥伴們!
C. 在DSP的TMS320F2812編程中c編譯器の作用是什麼。在連鏈接器中使用的cmd文件的作用是什
DSP晶元以其極高的精度,性能及運算速度等無與倫比的優點使它得到了十分廣泛的應用,TMS320F2812是TI公司生產的到目前為止用於數字控制領域的最好的DSP晶元,在對它的模擬開發過程中,編譯器生成的代碼和數據要由鏈接器分配到合適的存儲空間,通常鏈接器的命令文件.cmd文件是由用戶自己編寫的,編寫不當,就會使模擬開發不能進行,TI公司雖然在《TMS320C28x Optimizing C/C++ Compiler User』s Guide 6》和《TMS320C28x Assembly Language Tools User』s Guide 6》做了介紹,但內容卻比較散亂而且要求讀者對整個開發系統要有較全面的認識,這對於初學者來說是比較困難的。下面以TMS320F2812晶元為例,結合具體的模擬調試實例加以說明使大家能夠既快速又准確的掌握.cmd文件的分配方法。
1存儲空間的配置
TMS320F2812的DSP存儲器分為三個獨立選擇的空間-程序空間、數據空間和I/O空間,其中程序存儲器存放待執行的指令和執行中所用的系數(常數),可使用片內或片外的RAM、ROM或EPROM等來構成;數據存儲器存放指令執行中產生的數據,可使用片內或片外
的RAM和ROM來構成;I/O存儲器存放與映象外圍介面相關的數據,也可以作為附加的數據存儲空間使用。表1是TMS320F2812的存儲空間分布。
2CMD文件的分配方法
TI公司新的匯編器和鏈接器創建的目標文件採用一種COFF(通用目標文件格式),該目標文件格式更利於模塊化編程,為管理代碼段和目標系統存儲器提供了強有力和靈活的編程方法。用戶可以通過編寫鏈接命令文件(.cmd文件)將鏈接信息放在一個文件中,以便在多次使用同樣的鏈接信息時調用。在命令文件中使用兩個十分有用的偽指令MEMORY和SECTIONS,來指定實際應用中的存儲器結構和進行地址的映射。Memory用來指定目標存儲器結構,Memory下可以通過PAGE選項配置地址空間,鏈接器把每一頁都當作一個獨立的存儲空間。通常情況下,PAGE0代表程序存儲器用來存放程序,PAGE1代表數據存儲器,用來存放數據。由編譯器生成的可重定位的代碼和數據塊叫做「SECTIONS」(段),SECTIONS用來控制段的構成與地址分配。對於不同的系統配置,「SECTION」的分配方式也不相同,鏈接器通過「SECTIONS」來控制地址的分配,所以「SECTIONS」的分配就成了配置.cmd文件的重要環節。以下是對「SECTIONS」的定義及分配的詳細介紹。
(1)
被初始化的「SECTIONS」(包括數據表和可執行代碼)
.text它包括所有的可執行代碼和常數,必須放在程序頁;
.cinit它包括初始化的變數和常量表,要求放在程序頁;
.pinit它包括全局構造器(C++)初始化的變數和常量表,要求放在程序頁;
.const它包括字元串、聲明、以及被明確初始化過的全局和靜態變數,要求放在低地址的數據頁;
.econst它是在使用大存儲器模式時使用的,包括字元串、聲明、以及被明確初始化過的全局變數和靜態變數,可以放在數據頁的任何地方。
.switch它包括為轉換聲明設置的表格,可以放在程序頁也可以放在低地址的數據頁。
(2)未被初始化的「SECTIONS」(為程序運行中創建和存放的變數在存儲器中保留空間)
.bss它為全局變數和靜態變數保留空間。在程序開始運行時,C導入路徑把數據從.cinit節復制出去然後存在.bss節中,要求放在低地址的數據頁;
.ebss它是在遠(far)訪問(只用於C)和大存儲模式下使用,它為全局變數和靜態變數保留空間。在程序開始運行時,C導入路徑把數據從.cinit段復制出去然後存在.ebss節中,可以放在數據頁的任何地方;
.stack為C系統堆棧保留空間,這部分存儲器為用來將聲明傳給函數及為局部變數留出空間,要求放在低地址的數據頁;
.system動態存儲器分配保留空間。這個空間用於malloc函數,如果不使用malloc函數,這個段的大小就是0,要求放在低地址的數據頁;
.esystem動態存儲器分配保留空間,這個空間用於外部malloc函數,如果不使用外部malloc函數,這個段的大小就是0,可以放在數據頁的任何地方。
3舉例說明.cmd文件的分配方法
以下是模擬調試串列通信介面SCI時的.cmd文件的分配,已經在TMS320F2812模擬調試中得到了很好的應用。
MEMORY
{PAGE0:
/*ProgramMemory*/
RAMH0:origin=0x3F8000,length=0x001000
RAML0:origin=0x008000,length=0x001000
RAML1:origin=0x009000,length=0x001000
ROM:
origin=0x3FF000,length=0x000FC0
RESET: origin="0x3FFFC0",length=0x000002M
VECTORS:origin=0x3FFFC2,length=0x00003EM
PAGE1:/*DataMemory*/
RAMM0:origin=0x000000,length=0x000400
RAMM1:origin=0x000400,length=0x000400
RAMH0:origin=0x3F9000,length=0x001000
,,,
}
SECTIONS
{/*Allocateprogramareas:*/
.cinit
:>RAMH0
PAGE=0
.pinit
:>RAMH0
PAGE=0
.text
:>RAMH0
PAGE=0
.reset
:>RESET,PAGE=0,TYPE=DSECT
Vectors :>VECTORS,PAGE=0,TYPE=DSEC
/*:*/
.stack
:>RAMM0
PAGE=1
.ebss
:>RAMH0
PAGE=1
.esysmem :>RAMH0
PAGE=1
.econst :>RAMM1
PAGE=1
.switch :>RAMM1
PAGE=1
,,,
}
為充分利用18k×16位的SARAM,本例將高地址的8k×16位的H0 SARAM區分成兩部分,一部分用做存放程序放在PAGE0里,一部分用做存放數據放在PAGE1中以達到合理的分配;對實際模擬調試過程中的外圍幀frame0,frame1,frame2等的分配因為篇幅問題就不做具體介紹了。
4查看段的分配及使用情況
在cmd文件中包括各種各樣的鏈接器選項,每種選項代表不同的含義。其中,使用-m選項可以創建一個擴展名為.map的鏈接器(存儲器)分配映射文件,其語法為:-m filename(文件名)。鏈接器的map文件描述以下內容:
存儲器結構輸入和輸出段的定位在重新定位後外部符號的地址
通過map文件可以查看各段的分配情況,包括段的起始地址,使用的位元組數等配合cmd文件的使用,可確定各個段的使用情況,從而保證程序的正常運行和最小的空間使用。
5 VisualLinker可視化鏈接器
TI公司出品的DSP軟體開發環境CCS還提供了一種可視化生成存儲器配置文件的工具:VisualLinker可視化鏈接器。如果程序原來包含了一個鏈接器命令文件(.cmd文件),則當創
建可視化鏈接文件的時候,原來cmd文件中的內存配置仍然會被使用。如果讀者想修改內存配置,雙擊.rcp文件就會在CCS中打開可視化鏈接器的圖形界面,調整每個內存模塊的大小,直到認為合適,然後只需要重新連編,程序即可生成新的輸出文件,重復上面的步驟,直到出現滿意的結果。
D. C語言是由什麼語言編寫而成的
我想,你問的是 C語言編譯器 是用什麼語言寫的。
概括說,當今幾乎所有的實用的編譯器/解釋器都是用C語言編寫的,有一些語言比如Clojure,Jython等是基於JVM或者說是用Java實現的,IronPython等是基.NET實現的,但是Java和C#等本身也要依靠C/C++來實現,等於是間接調用了C。
世界上第一個C語言編譯器,是在B語言基礎上,用B語言與PDP匯編語言 編寫的。開發過程是先用匯編寫了一個最基本功能的子集C0,利用自編譯Self-Compile功能,或虛擬機CVM(C Language Virtual Machine)功能,增添新的東西,變C1, 按此法多次增添發展,滾雪球般用匯編把小雪球揉到一起,1生2,2生3,...成了C。C 再生萬物。
這里,該向C語言之父Dennis Ritchie(丹尼斯·里奇)致敬。