如果你有一个简单的C程序,比如
int main(void) {return 0;}
Run Code Online (Sandbox Code Playgroud)
它可以编译 gcc -o test test.c
.
据我所知,gcc执行编译,组装然后链接.后两步是通过运行as
和实现的ld
.
我可以使用生成汇编代码gcc -S test.c
.
你会在终端中输入什么内容,将汇编代码转换为可执行文件?
(这样做的原因是学习装配)
qui*_*oju 61
这些是使用gcc的不同阶段
gcc -E --> Preprocessor, but don't compile
gcc -S --> Compile but don't assemble
gcc -c --> Preprocess, compile, and assemble, but don't link
gcc with no switch will link your object files and generate the executable
Run Code Online (Sandbox Code Playgroud)
ZeZ*_*NiQ 18
// main.c
#include <stdio.h>
int main(void)
{
printf("Hello World !\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
对于上述简单的 hello world 程序的预处理、编译、组装和最终链接,请按照以下步骤操作:
步骤 1/4) 预处理 main.c 以生成 main.i:
$: gcc -E main.c -o main.i
Run Code Online (Sandbox Code Playgroud)
注意:您也可以直接调用 C 预处理器:
$: cpp main.c -o main.i
Run Code Online (Sandbox Code Playgroud)
步骤 2/4) 编译 main.i 以生成 main.s:
$: gcc -S main.i -o main.s
Run Code Online (Sandbox Code Playgroud)
步骤 3/4) 组装 main.s 以生成 main.o:
$: as main.s -o main.o
Run Code Online (Sandbox Code Playgroud)
注意:您可以使用 gcc 的 -c(小 C)标志组合上述步骤 1、2 和 3:
$: gcc -c main.s -o main.o // OR $: gcc -c main.c -o main.o
Run Code Online (Sandbox Code Playgroud)
步骤 4/4) 将 main.o 与其他必要的目标文件链接,即 crti.o 和 crtn.o(它们分别定义函数 prologs 和 epilogs)、crt1.o(包含用于引导程序初始执行的 _start 符号) , libc.so path or -lc flag for libc 然后最后设置动态链接器的名称,以生成动态链接的 ELF 可执行文件:
在 x86_64 上:
$: ld /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/x86_64-linux-gnu/crtn.o /usr/lib/x86_64-linux-gnu/crt1.o -lc main.o -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o main_ELF_executable
Run Code Online (Sandbox Code Playgroud)
或(如果您想指定 libc.so 的路径)
$: ld /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/x86_64-linux-gnu/crtn.o /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/libc.so main.o -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o main_ELF_executable
Run Code Online (Sandbox Code Playgroud)
在 32 位 ARM 上:
$: ld /usr/lib/arm-linux-gnueabihf/crti.o /usr/lib/arm-linux-gnueabihf/crtn.o /usr/lib/arm-linux-gnueabihf/crt1.o -lc main.o -dynamic-linker /lib/ld-linux.so.3 -o main_ELF_executable
Run Code Online (Sandbox Code Playgroud)
或(如果您想指定 libc.so 的路径)
$: ld /usr/lib/arm-linux-gnueabihf/crti.o /usr/lib/arm-linux-gnueabihf/crtn.o /usr/lib/arm-linux-gnueabihf/crt1.o /usr/lib/arm-linux-gnueabihf/libc.so main.o -dynamic-linker /lib/ld-linux-armhf.so.3 -o main_ELF_executable
Run Code Online (Sandbox Code Playgroud)
然后,您可以运行 ELF 可执行文件“main_ELF_executable”:
$: ./main_ELF_executable
Run Code Online (Sandbox Code Playgroud)
你好,世界 !
资料来源:
https://linux.die.net/man/1/gcc