從C源代碼到可執行文件的四個過程:預處理、編譯、匯編、鏈接

從C源代碼到可執行文件的四個過程:預處理、編譯、匯編、鏈接

總覽

在這里插入圖片描述

我們將在Linux操作系統中,以C語言的Hello World程序為例,用gcc編譯器分步執行這四個步驟。

我們有再熟悉不過的HelloWorld程序,hello.c

#include <stdio.h>int main(){printf("Hellow World.\n");return 0;
}

預處理

預處理階段 預處理器(cpp)根據以#字節開頭的命令,修改原始的C程序,

執行預處理命令:gcc -E hello.c -o hello.i,我們得到由.c文件得到.i文件:hello.i

# 1 "hello.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "hello.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 27 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 1 3 4
# 33 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 424 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 1 3 4
# 427 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4
# 428 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/long-double.h" 1 3 4
# 429 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4
# 425 "/usr/include/features.h" 2 3 4
# 448 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 1 3 4
# 10 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs-64.h" 1 3 4
# 11 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 2 3 4
# 449 "/usr/include/features.h" 2 3 4
# 34 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 2 3 4
# 28 "/usr/include/stdio.h" 2 3 4

編譯

編譯階段 編譯器(cc1)將文本文件hello.i翻譯成文本文件hello.s,它包含一個匯編語言程序。

執行編譯命令:gcc -S hello.i -o hello.s,我們得到由.i文件得到.s文件:hello.s,這就是匯編文件:

	.file	"hello.c".text.section	.rodata
.LC0:.string	"Hellow World.".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

匯編

匯編階段 匯編器(as)將hello.s翻譯成機器語言指令,把這些指令打包成一種叫做可重定位目標程序的格式,并保存在hello.o文件中,這是一個二進制文件,無法直接用文本編輯器查看。

執行編譯命令:gcc -c hello.s -o hello.o,我們得到由.s文件得到.o文件:hello.o,可重定向文件文件,這個文件就不是文本文件了,因此無法展示。

至此以上三步其實可以由-c參數直接得到可重定向文件:gcc -c hello.c -o hello.o,以上是為了說明預處理和編譯兩步,專門分步進行,以查看輸出。

鏈接

鏈接階段 hello程序調用了printf函數,它來自C標準庫,具體存在于一個已經預編譯好的printf.o文件,鏈接器(ld)負責將這個文件與我們的hello文件合并起來。

執行鏈接命令gcc hello.o -o hello,我們有.s文件得到可執行文件hello,直接./hello執行即可在命令行打印輸出Hellow World

Ref:CSAPP

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/532808.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/532808.shtml
英文地址,請注明出處:http://en.pswp.cn/news/532808.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

uboot引導linux內核,u-boot啟動內核的幾種方式

1.uboot啟動內核的代碼縮減如下&#xff1a;s getenv ("bootcmd");debug ("### main_loop: bootcmd\"%s\"\n", s ? s : "");if (bootdelay > 0 && s && !abortboot (bootdelay)){run_command (s, 0);}2.假設boot…

跟我一起寫makefile: 概述、介紹、規則

跟我一起寫makefile 概述、介紹、規則 轉自&#xff1a;https://seisman.github.io/how-to-write-makefile/rules.html 概述 什么是makefile&#xff1f;或許很多Windows的程序員都不知道這個東西&#xff0c;因為那些Windows的集成開發環境&#xff08;integrated developm…

linux內核中cent文件夾,Centos 中如何快速定制二進制的內核 RPM 包

1、rpm 制作前的環境準備&#xff1a;yum install -y ncurses-devel qt-devel rpm-build redhat-rpm-config asciidoc hmaccalc perl-ExtUtils-Embed xmlto audit-libs-devel binutils-devel elfutils-devel elfutils-libelf-devel newt-devel python-devel zlib-devel bc2、準…

TabError- inconsistent use of tabs and spaces in indentation 查驗及解決方法

TabError: inconsistent use of tabs and spaces in indentation 查驗及解決方法 報錯代碼 def eccv16(pretrainedTrue):model ECCVGenerator()if(pretrained):import torch.utils.model_zoo as model_zoomodel.load_state_dict(torch.load(/home/ps/.cache/torch/hub/check…

linux用xshell編輯文件,Linux遠程管理器xshell和xftp使用教程

Xshell 是一個強大的安全終端模擬軟件&#xff0c;它支持SSH1, SSH2, 以及Microsoft Windows 平臺的TELNET 協議。Xftp 是一個基于 MS windows 平臺的功能強大的SFTP、FTP 文件傳輸軟件。安裝完畢后打開xshell設置網站帳號信息設置主機信息設置服務器帳號設置字符集編碼設置好了…

strict=False 但還是size mismatch for []: copying a param with shape [] from checkpoint,the shape in cur

strictFalse 但還是size mismatch for []: copying a param with shape [] from checkpoint,the shape in cur 問題 我們知道通過 model.load_state_dict(state_dict, strictFalse)可以暫且忽略掉模型和參數文件中不匹配的參數&#xff0c;先將正常匹配的參數從文件中載入模…

linux中權限765啥意思,Linux中的文件權限

Linux系統中的每一個文件都與多種權限類型相關聯。在這些權限中&#xff0c;我們主要和三類權限打交道&#xff1a;用戶(user)、用戶組(group)和其他用戶(others)。用戶是文件的所有者&#xff1b;用戶組是指和文件所有者在同一組的其他多個用戶的集合&#xff1b;其他用戶是除…

CV中的色彩空間大全

HSI、HSV、RGB、CMY、CMYK、HSL、HSB、Ycc、XYZ、Lab、YUV顏色模型 HSV顏色空間 HSV(hue,saturation,value)顏色空間的模型對應于圓柱坐標系中的一個圓錐形子集&#xff0c;圓錐的頂面對應于V1. 它包含RGB模型中的R1&#xff0c;G1&#xff0c;B1 三個面&#xff0c;所代表的…

linux 系統調用時怎么知道當前上下文屬于那個進程,linux – 編寫系統調用來計算進程的上下文切換...

如果您的系統調用只應報告統計信息,則可以使用內核中已有的上下文切換計數代碼.struct rusage {...long ru_nvcsw; /* voluntary context switches */long ru_nivcsw; /* involuntary context switches */};您可以通過運行來嘗試&#xff1a;$/usr/bin/time -v /bin/ls -R....V…

linux串口緩沖區的大小,linux-----------串口設置緩沖器的大小

轉自:http://stackoverflow.com/questions/10815811/linux-serial-port-reading-can-i-change-size-of-input-bufferYou want to use the serial IOCTL TIOCSSERIAL which allows changing both receive buffer depth and send buffer depth (among other things). The maximum…

FLOPs、FLOPS、Params的含義及PyTorch中的計算方法

FLOPs、FLOPS、Params的含義及PyTorch中的計算方法 含義解釋 FLOPS&#xff1a;注意全大寫&#xff0c;是floating point operations per second的縮寫&#xff08;這里的大S表示second秒&#xff09;&#xff0c;表示每秒浮點運算次數&#xff0c;理解為計算速度。是一個衡量…

設置中文linux輸入ubuntu,Linux_ubuntu怎么設置成中文?ubuntu中文設置圖文方法,  很多朋友安裝ubuntu后,發 - phpStudy...

ubuntu怎么設置成中文&#xff1f;ubuntu中文設置圖文方法很多朋友安裝ubuntu后&#xff0c;發現都是英文&#xff0c;看不懂要怎么辦?其實ubuntu是可以設置成中文的&#xff0c;下文小編就為大家帶來ubuntu中文的設置方法&#xff0c;一起去看下設置方法吧。ubuntu中文設置方…

科普 | 單精度、雙精度、多精度和混合精度計算的區別是什么?

科普 | 單精度、雙精度、多精度和混合精度計算的區別是什么? 轉自&#xff1a;https://zhuanlan.zhihu.com/p/93812784 我們提到圓周率 π 的時候&#xff0c;它有很多種表達方式&#xff0c;既可以用數學常數3.14159表示&#xff0c;也可以用一長串1和0的二進制長串表示。 …

linux 磁盤分配 簡書,linux 磁盤分區

1物理磁盤的構成&#xff1a; 盤面&#xff1a;由一圈一圈的磁道組成機械手臂&#xff1a;讀取數據主軸馬達&#xff1a;幫助機械手臂轉動2 扇區&#xff1a;磁盤上存取數據的最小單位512字節按照扇區分配大小&#xff0c;如果數據只有一字節也會占用512字節簇&#xff1a;用若…

條件控制與條件傳送詳解

條件控制與條件傳送詳解 提要 CSAPP3e中文譯本 3.6.5 用條件控制來實現條件分支 3.6.6 用條件傳送來實現條件分支 CSAPP3e第三章前面主要是介紹了機器級代碼的二進制形式和匯編形式、反匯編、x86匯編的基礎指令、條件碼及其訪問方式等。 在介紹到匯編語言的條件分支時分了兩…

聯合體(union)的使用方法及其本質

聯合體&#xff08;union&#xff09;的使用方法及其本質 轉自&#xff1a;https://blog.csdn.net/huqinwei987/article/details/23597091 有些基礎知識快淡忘了&#xff0c;所以有必要復習一遍&#xff0c;在不借助課本死知識的前提下做些推理判斷&#xff0c;溫故知新。 1…

linux設備驅動之串口移植,Linux設備驅動之UART驅動結構

一、對于串口驅動Linux系統中UART驅動屬于終端設備驅動&#xff0c;應該說是實現串口驅動和終端驅動來實現串口終端設備的驅動。要了解串口終端的驅動在Linux系統的結構就先要了解終端設備驅動在Linux系統中的結構體系&#xff0c;一方面自己了解的不夠&#xff0c;另一發面關于…

linux python復制安裝,復制一個Python全部環境到另一個環境,python另一個,導出此環境下安裝的包...

復制一個Python全部環境到另一個環境&#xff0c;python另一個,導出此環境下安裝的包導出此環境下安裝的包的版本信息清單pipfreeze>requirements.txt聯網&#xff0c;下載清單中的包到all-packet文件夾[[email protected] ~]# pip download -d ./all-packet -r requirement…

NVIDIA英偉達的Multi-GPU多卡通信框架NCCL

NVIDIA英偉達的Multi-GPU多卡通信框架NCCL 筆者注&#xff1a;NCCL 開源項目地址&#xff1a;https://github.com/NVIDIA/nccl 轉自&#xff1a;https://www.zhihu.com/question/63219175/answer/206697974 NCCL是Nvidia Collective multi-GPU Communication Library的簡稱&…

C語言n個坐標點間的最大距離,c語言已知兩點坐標,求另一點到穿過這兩點的直線最短距離。...

c語言已知兩點坐標&#xff0c;求另一點到穿過這兩點的直線最短距離。以下文字資料是由(歷史新知網www.lishixinzhi.com)小編為大家搜集整理后發布的內容&#xff0c;讓我們趕快一起來看一下吧&#xff01;c語言已知兩點坐標&#xff0c;求另一點到穿過這兩點的直線最短距離。#…