女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C語言生成可執(zhí)行二進(jìn)制文件的具體過程

小杜的芯片驗(yàn)證日記 ? 來源:數(shù)字芯片驗(yàn)證日記 ? 2024-10-21 14:30 ? 次閱讀

Hi,我是小杜。SoC驗(yàn)證中會(huì)經(jīng)常使用C語言,所以需要知道C語言生成可執(zhí)行二進(jìn)制文件的具體過程以及如何從生成的中間文件讀取有用信息。因?yàn)樾《攀寝D(zhuǎn)行做數(shù)字IC驗(yàn)證,SoC的知識(shí)需要重頭開始學(xué),如果錯(cuò)誤,還請(qǐng)批評(píng)指正。

C語言源碼到生成可執(zhí)行文件的過程通常包括預(yù)處理(Preprocessing)編譯(Compilation)匯編(Assembly)鏈接(Linking)等多個(gè)步驟,每個(gè)步驟都有其特定的任務(wù)和產(chǎn)物。下面,小杜通過一個(gè)具體的例子詳細(xì)講述這個(gè)過程,以及如何通過反匯編(Disassembly)來查看匯編、鏈接產(chǎn)生的不可讀二進(jìn)制目標(biāo)文件。

C語言源碼準(zhǔn)備

首先編寫3個(gè)文件,一個(gè)是主程序 main.c,另一個(gè)是功能函數(shù) func.c,外加一個(gè)頭文件 func.h。具體路徑為:

project/
│
├──main.c
├── func.c
└── func.h

代碼如下:

// main.c
#include 
#include


int main() {
    int result = add(5, 3);
    printf("Result: %d
", result);
    return 0;
}
// func.c
#include "func.h"


int add(int a, int b) {
    return a + b;
}
// func.h
#ifndef FUNC_H
#define FUNC_H


int add(int a, int b);


#endif

分步生成可執(zhí)行文件

1. 預(yù)處理(Preprocessing)

預(yù)處理器處理 #include、#define 等指令,并生成一個(gè)預(yù)處理后的文件。可以使用 -E 選項(xiàng)運(yùn)行預(yù)處理器。

gcc-Emain.c-omain.i-I .
gcc-Efunc.c-ofunc.i-I .

main.i 和 func.i 是預(yù)處理后的文件,包含展開后的宏和頭文件內(nèi)容。以main.i為例,預(yù)處理后的文件可能會(huì)非常長,因?yàn)樗械暮辍㈩^文件都被展開。預(yù)處理器在預(yù)處理文件中插入了很多#開頭的行,提供了文件和行號(hào)信息用于調(diào)試和錯(cuò)誤報(bào)告。下面截圖展示了main.i文件中的主要部分:

d77efbbada0c87c9d2452c4697b7a758.png

源碼中所有的注釋都會(huì)在預(yù)處理階段被去除。如果源碼中有條件編譯指令,比如`ifdef,`ifndef,`if 等,預(yù)處理器會(huì)根據(jù)條件和結(jié)果保留或刪除相應(yīng)的代碼。

預(yù)處理文件的用途

調(diào)試:通過查看預(yù)處理后的文件,可以檢查宏和頭文件是否正確展開,從而幫助調(diào)試編譯問題。

了解代碼結(jié)構(gòu):預(yù)處理文件展示了代碼的最終形態(tài),包括所有的頭文件和宏定義,這對(duì)理解代碼的整體結(jié)構(gòu)很有幫助。

性能優(yōu)化:分析預(yù)處理后的代碼,有助于識(shí)別和優(yōu)化編譯時(shí)間和代碼冗余問題。

2.編譯(Compilation)

編譯器將預(yù)處理后的C代碼轉(zhuǎn)換為匯編代碼。可以使用 -S 選項(xiàng)生成匯編代碼。

gcc -s main.i -o main.s -I .
gcc-sfunc.i -o func.s -I .

231418c4da982fbcdf43578c09ee96bf.png

從生成的匯編代碼中我們可以看到文件和段定義函數(shù)入口和棧幀設(shè)置調(diào)用add函數(shù)調(diào)用printf函數(shù)以及函數(shù)退出

匯編代碼可能是調(diào)試過程中接觸的最底層部分,SoC驗(yàn)證過程中如果CPU卡死,通過記錄的寄存器內(nèi)容、程序計(jì)數(shù)器(PC)和堆棧指針(SP),找到對(duì)應(yīng)的匯編指令就可以知道CPU卡死的具體位置,這對(duì)調(diào)試和找出代碼bug十分重要。從匯編代碼中我們可以得到如下信息:

函數(shù)調(diào)用和參數(shù)傳遞

通過匯編代碼可以看到函數(shù)是如何調(diào)用的,以及參數(shù)是如何傳遞的。例如,在x86-64架構(gòu)中,前六個(gè)整數(shù)參數(shù)通過寄存器(如EDI、ESI、EDX等)傳遞。

棧幀管理

匯編代碼展示了棧幀是如何創(chuàng)建和銷毀的,尤其是通過 pushq %rbp、movq %rsp, %rbp 和 leave 指令。這有助于理解函數(shù)調(diào)用過程中棧的變化。

變量和寄存器操作
匯編代碼展示了如何使用寄存器和內(nèi)存操作來實(shí)現(xiàn)程序邏輯。例如,通過 movl 指令可以看到如何在寄存器和內(nèi)存之間傳遞數(shù)據(jù)。

調(diào)試和優(yōu)化

通過分析匯編代碼,可以發(fā)現(xiàn)編譯器生成的代碼是否高效。例如,可以識(shí)別不必要的指令或冗余操作,進(jìn)而優(yōu)化代碼。

3. 匯編(Assembly)與反匯編(Disassembly)

匯編器將匯編代碼轉(zhuǎn)換為機(jī)器碼,生成目標(biāo)文件。可以使用 -c 選項(xiàng)生成目標(biāo)文件。這一步開始生成的二進(jìn)制目標(biāo)文件已經(jīng)不能看了,不過我們還是可以通過反匯編來獲取有用信息。

gcc -c main.s -o main.o -I .
gcc-cfunc.s-ofunc.o -I .

fa89308c9cb7370bccd12364056881b3.jpg

main.o 和func.o 是目標(biāo)文件,包含機(jī)器代碼、符號(hào)表和調(diào)試信息,但它們是二進(jìn)制格式,不像匯編代碼那樣直接可讀。我們可以使用工具來查看分析目標(biāo)文件,以獲取有用的信息,比如使用objdump。

反匯編

通過反匯編可以查看目標(biāo)文件的機(jī)器碼、段信息以及符號(hào)表。

objdump-dmain.o#反匯編目標(biāo)文件,顯示機(jī)器碼
objdump-hmain.o#顯示目標(biāo)文件的段信息
objdump -t main.o # 顯示符號(hào)表

比如反匯編產(chǎn)生機(jī)器碼(工作中一般不會(huì)接觸這么深,這里只是舉例):

11cf077e50f573983ed7897c960189a5.png

4. 鏈接(Linking)

鏈接器將多個(gè)目標(biāo)文件和庫文件鏈接在一起,生成最終的可執(zhí)行文件。

gccmain.ofunc.o-omyprogram

65949ea6b1f1e83e7bd9af8eff7a256d.png

myprogram 是最終生成的可執(zhí)行文件。二進(jìn)制可執(zhí)行文件不可讀,但同樣可以使用objdump來查看可執(zhí)行文件的有用信息,比如:

objdump -f myprogram # 查看可執(zhí)行文件功能

該輸出展示了可執(zhí)行文件的基本信息,包括文件格式、架構(gòu)、標(biāo)志和程序入口信息。

5a89bd9fb1e5320b578b1595d47f5580.png

一步到位的編譯和鏈接

通常我們會(huì)直接使用 gcc 命令來一步到位完成整個(gè)過程,而不需要手動(dòng)執(zhí)行每個(gè)步驟:

gccmain.cfunc.-omyprogram

這個(gè)命令會(huì)自動(dòng)處理上述所有步驟,并生成最終的可執(zhí)行文件 myprogram。

總結(jié) 讓我們來總結(jié)一下C語言源碼到最終的可執(zhí)行二進(jìn)制文件的4個(gè)過程分別干了哪些事:

預(yù)處理:處理頭文件包含和宏定義,生成一個(gè)單一的C源文件。

編譯:將C源文件轉(zhuǎn)換為匯編代碼,這一步會(huì)進(jìn)行語法檢查和優(yōu)化。

匯編:將匯編代碼轉(zhuǎn)換為目標(biāo)文件,目標(biāo)文件是二進(jìn)制格式的機(jī)器碼,但還不是完整的可執(zhí)行程序。

鏈接:將多個(gè)目標(biāo)文件和庫文件鏈接在一起,解決符號(hào)引用問題(如函數(shù)和變量的定義和聲明),生成最終的可執(zhí)行文件。

感謝你看到這里。項(xiàng)目工作中,其實(shí)工具鏈建立好之后一般也就不會(huì)去關(guān)注這些過程了,寫完C代碼走腳本流程即可,但如果出現(xiàn)bug,了解這一過程對(duì)解決bug就很重要了!

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 二進(jìn)制
    +關(guān)注

    關(guān)注

    2

    文章

    803

    瀏覽量

    42112
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7629

    瀏覽量

    140126
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4367

    瀏覽量

    64059
  • 預(yù)處理
    +關(guān)注

    關(guān)注

    0

    文章

    33

    瀏覽量

    10598

原文標(biāo)題:【SoC】C code如何生成二進(jìn)制可執(zhí)行文件?實(shí)例詳解

文章出處:【微信號(hào):小杜的芯片驗(yàn)證日記,微信公眾號(hào):小杜的芯片驗(yàn)證日記】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    不同機(jī)器上生成不同的二進(jìn)制文件

    模型 - 長堆棧(+ modsl0)我們的目標(biāo)可執(zhí)行文件是* .s19格式。但是,當(dāng)我們構(gòu)建我們的軟件時(shí),它會(huì)在不同的機(jī)器上生成不同的二進(jìn)制文件!所有設(shè)置都相同,并且正在使用相同的工作
    發(fā)表于 11-16 10:27

    一個(gè)源文件生成二進(jìn)制可執(zhí)行文件的步驟

    = var_value3 funcmainvim filename.c=> srcgcc 編譯器filename.c => a.out一個(gè)源文件生成
    發(fā)表于 10-27 07:04

    二進(jìn)制

    二進(jìn)制   二進(jìn)制與十進(jìn)制的區(qū)別在于數(shù)碼的個(gè)數(shù)和進(jìn)位規(guī)律有很大的區(qū)別,顧名思義,二進(jìn)制的計(jì)數(shù)規(guī)律為逢二進(jìn)一,是以2為基數(shù)的計(jì)數(shù)體制。10這
    發(fā)表于 04-06 23:48 ?8411次閱讀
    <b class='flag-5'>二進(jìn)制</b>

    C語言入門教程-二進(jìn)制文件

    二進(jìn)制文件 二進(jìn)制文件非常類似于結(jié)構(gòu)體數(shù)組,只不過這些結(jié)構(gòu)體被保存在一個(gè)磁盤文件而非內(nèi)存數(shù)組中。因?yàn)槭鞘褂么疟P保存
    發(fā)表于 07-29 14:24 ?2023次閱讀

    二進(jìn)制編碼和二進(jìn)制數(shù)據(jù)

    二進(jìn)制編碼和二進(jìn)制數(shù)據(jù)   二進(jìn)制編碼是計(jì)算機(jī)內(nèi)使用最多的碼制,它只使用兩個(gè)基本符號(hào)"0"和"1",并且通過由這兩個(gè)符號(hào)組成的
    發(fā)表于 10-13 16:22 ?4974次閱讀

    二進(jìn)制電平,什么是二進(jìn)制電平

    二進(jìn)制電平,什么是二進(jìn)制電平 在二進(jìn)制數(shù)字通信系統(tǒng)中,每個(gè)碼元或每個(gè)符號(hào)只能是“1”和“0”兩個(gè)狀態(tài)之一。若將每個(gè)碼元可能取的狀態(tài)增
    發(fā)表于 03-17 16:51 ?2464次閱讀

    具有X86到ARM二進(jìn)制翻譯和執(zhí)行功能的SoC系統(tǒng)設(shè)計(jì)

      二進(jìn)制翻譯是一種直接翻譯可執(zhí)行二進(jìn)制程序的技術(shù),能夠把一種處理器上的二進(jìn)制程序翻譯到另外一種處理器上執(zhí)行。它使得不同處理器之間的
    發(fā)表于 09-07 10:22 ?2261次閱讀
    具有X86到ARM<b class='flag-5'>二進(jìn)制</b>翻譯和<b class='flag-5'>執(zhí)行</b>功能的SoC系統(tǒng)設(shè)計(jì)

    二進(jìn)制加法程序【C語言版】

    二進(jìn)制加法程序【C語言版】二進(jìn)制加法程序【C語言版】二進(jìn)制
    發(fā)表于 12-29 11:03 ?0次下載

    二進(jìn)制加法程序【C語言+匯編版】

    二進(jìn)制加法程序【C語言+匯編版】,多種集合,符合同時(shí)愛好C語言+匯編的學(xué)習(xí)者的胃口。
    發(fā)表于 01-06 11:10 ?0次下載

    C語言教程之十進(jìn)制轉(zhuǎn)換為二進(jìn)制

    C語言教程之十進(jìn)制轉(zhuǎn)換為二進(jìn)制,很好的C語言資料,快來學(xué)習(xí)吧。
    發(fā)表于 04-22 11:06 ?0次下載

    C語言編程二進(jìn)制位操作符

    C語言編程二進(jìn)制位操作符
    發(fā)表于 03-30 14:09 ?6次下載

    Visual-C#數(shù)據(jù)庫存取二進(jìn)制字段數(shù)據(jù)

    現(xiàn)代的數(shù)據(jù)庫不僅要存放數(shù)值和字符等數(shù)據(jù),還要存放一些二進(jìn)制類型的文件,常見的如圖片文件、動(dòng)態(tài)連接庫、可執(zhí)行文件等。對(duì)于數(shù)值和字符這些普通數(shù)據(jù)類型,利用上一章中介紹的編輯記錄的方法是完全
    發(fā)表于 04-03 15:12 ?14次下載

    C語言程序內(nèi)存布局該關(guān)注哪些內(nèi)容

    C語言代碼(文本文件)形成可執(zhí)行程序(二進(jìn)制文件),需要經(jīng)過編譯-匯編-連接三個(gè)階段。編譯
    發(fā)表于 05-07 08:03 ?1049次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>程序內(nèi)存布局該關(guān)注哪些內(nèi)容

    C語言程序運(yùn)行流程包含哪些環(huán)節(jié)

    C語言并不能直接被計(jì)算機(jī)所理解,需要將C語言轉(zhuǎn)變成可執(zhí)行代碼,即二進(jìn)制代碼。在
    發(fā)表于 11-07 15:05 ?1.3w次閱讀

    在Linux上分析二進(jìn)制文件的10種方法

    這將是你進(jìn)行二進(jìn)制分析的起點(diǎn)。我們每天都在與文件打交道,并非所有的文件都是可執(zhí)行類型,除此之外還有各種各樣的文件類型。在你開始之前,你需要了
    的頭像 發(fā)表于 06-18 17:32 ?3424次閱讀