第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

編譯/鏈接過程是如何工作的?

編譯/鏈接過程是如何工作的?

C C++
繁花如伊 2019-05-30 17:20:24
編譯/鏈接過程是如何工作的?編譯和鏈接過程是如何工作的?(注:這是指堆棧溢出的C+常見問題。如果您想批評(píng)以這種形式提供常見問題的想法,那么在元網(wǎng)站上發(fā)布的文章引發(fā)了這一切就是這樣做的地方。對(duì)該問題的回答將在C+聊天室你的答案很可能會(huì)被那些想出這個(gè)想法的人讀懂。)
查看完整描述

4 回答

?
烙印99

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超13個(gè)贊

C+程序的編譯包括三個(gè)步驟:

  1. 預(yù)處理:預(yù)處理程序采用C+源代碼文件,并處理#includeS,#defineS和其他預(yù)處理指令。這個(gè)步驟的輸出是一個(gè)“純”C+文件,沒有預(yù)處理指令。

  2. 編譯:編譯器獲取預(yù)處理器的輸出并從中生成一個(gè)對(duì)象文件.

  3. 鏈接:鏈接器獲取編譯器生成的對(duì)象文件,并生成庫或可執(zhí)行文件。

預(yù)處理

預(yù)處理程序處理預(yù)處理指令,就像#include#define。它不知道C+的語法,這就是為什么必須謹(jǐn)慎使用它的原因。

它一次工作在一個(gè)C+源文件上,方法是#include具有相應(yīng)文件內(nèi)容的指令(通常只是聲明),替換宏(#define),并根據(jù)以下內(nèi)容選擇文本的不同部分:#if#ifdef#ifndef指令。

預(yù)處理器工作在預(yù)處理令牌流上。宏替換定義為用其他令牌替換令牌(操作符)。##當(dāng)有意義時(shí),啟用合并兩個(gè)令牌)。

在所有這些之后,預(yù)處理器產(chǎn)生一個(gè)單一的輸出,這是由上面描述的轉(zhuǎn)換產(chǎn)生的令牌流。它還添加了一些特殊的標(biāo)記,告訴編譯器每一行來自哪里,這樣它就可以使用這些標(biāo)記來生成合理的錯(cuò)誤消息。

在此階段,可以通過巧妙地使用#if#error指令。

編撰

編譯步驟對(duì)預(yù)處理程序的每個(gè)輸出執(zhí)行。編譯器解析純C+源代碼(現(xiàn)在沒有任何預(yù)處理器指令)并將其轉(zhuǎn)換為程序集代碼。然后調(diào)用底層后端(工具鏈中的匯編程序),將該代碼組裝成生成某種格式的實(shí)際二進(jìn)制文件的機(jī)器代碼(ELF,COFF,a.out,.)。此對(duì)象文件包含輸入中定義的符號(hào)的編譯代碼(二進(jìn)制形式)。對(duì)象文件中的符號(hào)按名稱引用。

對(duì)象文件可以引用未定義的符號(hào)。如果使用聲明,而不提供聲明的定義,則會(huì)出現(xiàn)這種情況。編譯器不介意這一點(diǎn),只要源代碼格式良好,編譯器就會(huì)很高興地生成對(duì)象文件。

編譯器通常允許您在此時(shí)停止編譯。這非常有用,因?yàn)槭褂盟?,您可以分別編譯每個(gè)源代碼文件。它提供的優(yōu)點(diǎn)是您不需要重新編譯一切如果您只更改一個(gè)文件。

生成的對(duì)象文件可以放在稱為靜態(tài)庫的特殊檔案中,以便以后更容易重用。

在這個(gè)階段,報(bào)告了“常規(guī)”編譯器錯(cuò)誤,比如語法錯(cuò)誤或失敗的過載解析錯(cuò)誤。

鏈接

鏈接器是編譯器生成的對(duì)象文件的最終編譯輸出。這個(gè)輸出可以是一個(gè)共享的(或者是動(dòng)態(tài)的)庫(雖然名稱相似,但它們與前面提到的靜態(tài)庫沒有多少共同點(diǎn)),也可以是一個(gè)可執(zhí)行文件。

它通過用正確的地址替換對(duì)未定義符號(hào)的引用來鏈接所有對(duì)象文件。這些符號(hào)中的每一個(gè)都可以在其他對(duì)象文件或庫中定義。如果它們是在標(biāo)準(zhǔn)庫以外的庫中定義的,則需要將它們告知鏈接器。

在這個(gè)階段,最常見的錯(cuò)誤是缺少定義或重復(fù)定義。前者意味著定義不存在(即它們不被寫入),或者它們所在的對(duì)象文件或庫沒有提供給鏈接器。后者是顯而易見的:在兩個(gè)不同的對(duì)象文件或庫中定義了相同的符號(hào)。


查看完整回答
反對(duì) 回復(fù) 2019-05-30
?
慕雪6442864

TA貢獻(xiàn)1812條經(jīng)驗(yàn) 獲得超5個(gè)贊

精簡(jiǎn)是指CPU從內(nèi)存地址加載數(shù)據(jù),將數(shù)據(jù)存儲(chǔ)到內(nèi)存地址,然后從內(nèi)存地址順序執(zhí)行指令,在處理的指令序列中有一些條件跳轉(zhuǎn)。這三種指令中的每一種都涉及到計(jì)算要在機(jī)器指令中使用的存儲(chǔ)器單元的地址。由于機(jī)器指令的長度取決于所涉及的特定指令,而且由于我們?cè)跇?gòu)建機(jī)器代碼時(shí)將其中的可變長度串在一起,所以在計(jì)算和構(gòu)建任何地址時(shí)需要兩個(gè)步驟。

首先,我們盡可能地安排內(nèi)存分配,然后才能知道每個(gè)單元的確切情況。我們計(jì)算出字節(jié),或單詞,或構(gòu)成指令、文字和任何數(shù)據(jù)的任何東西。我們只是開始分配內(nèi)存和構(gòu)建值,這些值將在我們運(yùn)行時(shí)創(chuàng)建程序,并記下我們需要返回并修復(fù)地址的任何地方。在那個(gè)地方,我們放置一個(gè)假人來填充位置,這樣我們就可以繼續(xù)計(jì)算內(nèi)存大小。例如,我們的第一個(gè)機(jī)器代碼可能需要一個(gè)單元格。下一個(gè)機(jī)器代碼可能包含3個(gè)單元,包括一個(gè)機(jī)器代碼單元和兩個(gè)地址單元?,F(xiàn)在我們的地址指針是4。我們知道機(jī)器單元是什么,這是OP代碼,但是我們必須等待計(jì)算地址單元格中的內(nèi)容,直到我們知道數(shù)據(jù)的位置,即數(shù)據(jù)的機(jī)器地址是什么。

如果只有一個(gè)源文件,理論上編譯器可以在沒有鏈接器的情況下生成完全可執(zhí)行的機(jī)器代碼。在兩次傳遞過程中,它可以計(jì)算出任何機(jī)器加載或存儲(chǔ)指令所引用的所有數(shù)據(jù)單元的所有實(shí)際地址。它可以計(jì)算任何絕對(duì)跳轉(zhuǎn)指令所引用的所有絕對(duì)地址。這是一個(gè)簡(jiǎn)單的編譯器,就像Forth Work中的編譯器,沒有鏈接器。

鏈接器允許單獨(dú)編譯代碼塊。這可以加快構(gòu)建代碼的整個(gè)過程,并允許在以后如何使用這些塊時(shí)具有一定的靈活性,換句話說,它們可以在內(nèi)存中重新定位,例如在每個(gè)地址中添加1000個(gè)地址,以使塊增加1000個(gè)地址單元格。

所以編譯器輸出的是尚未完全構(gòu)建的粗略的機(jī)器代碼,而是布局好的,這樣我們就知道了所有東西的大小,換句話說,我們就可以開始計(jì)算所有絕對(duì)地址的位置。編譯器還輸出一個(gè)符號(hào)列表,這些符號(hào)是名稱/地址對(duì)。符號(hào)將模塊中機(jī)器代碼中的內(nèi)存偏移量與名稱相關(guān)聯(lián)。偏移量是到模塊中符號(hào)的存儲(chǔ)器位置的絕對(duì)距離。

那就是我們找到鏈接器的地方。鏈接器首先將所有這些機(jī)器代碼塊連接到一起,并記下每個(gè)代碼的起始位置。然后,通過將模塊內(nèi)部的相對(duì)偏移量和模塊在較大布局中的絕對(duì)位置相加,計(jì)算要固定的地址。

顯然,我過于簡(jiǎn)化了這一點(diǎn),所以您可以嘗試?yán)斫馑椅夜室獠皇褂脤?duì)象文件、符號(hào)表等術(shù)語。這對(duì)我來說是混亂的一部分。


查看完整回答
反對(duì) 回復(fù) 2019-05-30
  • 4 回答
  • 0 關(guān)注
  • 799 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)