日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

gcc a.c 究竟经历了什么

發布時間:2025/4/5 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 gcc a.c 究竟经历了什么 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

link
你知道一次gcc命令究竟經歷了什么嗎?

我們先來看一段C語言示例源代碼:

// test.cc #include <stdio.h>int main() {printf("Hello 程序喵\n");return 0; } gcc test.cc./a.out Hello 程序喵


我們平時都會使用gcc來編譯程序,這一行簡單的命令其實經歷了很多復雜的過程:

  • 預處理
  • 編譯
  • 匯編
  • 鏈接

首先使用file看一下test.cc文件類型:

file test.cc test.c: C source, UTF-8 Unicode text

我們接下來看看這每個過程都做了什么?

預處理

命令:

gcc -E test.cc -o test.i 或者 cpp test.cc -o test.i
這里可以看出預處理后的文件和預處理前的文件類型是相同的,都是文本文件,也可以直接查看test.i的內容,里面代碼較多,就不貼上來了。
其實預處理主要操作有這幾個:
  • 展開所有#define宏定義,進行文本替換
  • 刪除程序中所有的注釋
  • 處理所有的條件編譯,#if、#ifdef、#elif等
  • 處理所有的#include指令,把這些頭文件的內容都復制到引用的源文件中
  • 添加行號和文件名標識,方便編譯器產生警告及調試信息
  • 保留所有的#pragma編譯器指令,因為編譯器會使用他們

編譯(生成匯編代碼)

命令:

gcc -S test.cc -o test.s

再查看文件類型

file test.s test.s: assembler source, ASCII text .file "test.cc".text.section .rodata .LC0:.string "Hello \347\250\213\345\272\217\345\226\265".text.globl main.type main, @function main: .LFB0:.cfi_startprocpushq %rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq %rsp, %rbp.cfi_def_cfa_register 6leaq .LC0(%rip), %rdicall puts@PLTmovl $0, %eaxpopq %rbp.cfi_def_cfa 7, 8ret.cfi_endproc .LFE0:.size main, .-main.ident "GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0".section .note.GNU-stack,"",@progbits

如圖二,編譯過程就是把預處理后的文件進行一系列操作生成相應的匯編文件:
  • 詞法分析:又稱詞法掃描,通過掃描器,利用有限狀態機的算法將源碼中的字符串分割成一系列記號,如加減乘除數字括號等。
  • 語法分析:使用語法分析器對詞法分析產生的記號運用上下文無關語法的手段進行語法分析,產生語法分析樹。這期間如果表達式不合法(括號不匹配等),就會報錯。
  • 語義分析:語法分析檢查表達式是否合法,語義分析檢查表達式是否有意義,如浮點型整數賦值給指針,編譯器就會報錯。
  • 中間語言生成:做一些語法樹優化,如6+2=8。
  • 目標代碼生成及優化:將中間代碼生成目標匯編代碼。

匯編

命令:

gcc -c test.s -o test.o 或 as test.s -o test.o 7f45 4c46 0201 0100 0000 0000 0000 0000 0100 3e00 0100 0000 0000 0000 0000 0000 0000 0000 0000 0000 d002 0000 0000 0000 ... ... ... 0000 0000 0000 0000 6802 0000 0000 0000 6100 0000 0000 0000 0000 0000 0000 0000 0100 0000 0000 0000 0000 0000 0000 0000

查看文件類型:

file test.o testt.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

使用匯編器將匯編代碼轉成機器可以執行的指令,其實就是將匯編指令和機器指令按照對照表一一翻譯。

鏈接

為什么匯編器不直接生成可執行文件而是生成一個目標文件呢,因為一個文件需要依賴其它好多個庫,這些庫的符號需要通過鏈接過程才可以互相配合生成一個可執行文件,需要經歷地址和空間分配、符號決議、重定位等步驟,這塊內容較多,后續會詳細介紹,現在我們可以簡單的通過ldd查看一下可執行程序需要依賴的庫,這些庫都需要在鏈接過程中被鏈接才可以使用。
ldd a.out linux-vdso.so.1 (0x00007ffe59c5b000)libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007efcd6269000)/lib64/ld-linux-x86-64.so.2 (0x00007efcd685c000)

總結

以上是生活随笔為你收集整理的gcc a.c 究竟经历了什么的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。