手动运行gcc的步骤,编译,组装,链接

时间:2011-12-15 22:52:06

标签: c gcc

如果你有一个简单的C程序,比如

int main(void) {return 0;}

可以使用gcc -o test test.c编译。

据我所知,gcc执行编译,汇编然后链接。后两个步骤是通过运行asld来实现的。

我可以使用gcc -S test.c生成汇编代码。

您要在终端中输入什么内容,将汇编代码转换为可执行文件?

(这样做的原因是学习装配)

6 个答案:

答案 0 :(得分:57)

这些是使用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

答案 1 :(得分:3)

gcc test.s -o test将为您test编译test.s

NASM也可能值得您花时间 - 它可能比编译程序集gcc更容易/更友好。

答案 2 :(得分:1)

执行gcc -S -o test.s test.c后,输入gcc -o test test.s

答案 3 :(得分:1)

// main.c
#include <stdio.h>

int main(void)
{
        printf("Hello World !\n");
        return 0;
}

要进行预处理,编译,组装,然后最终链接上述简单的hello world程序,请执行以下步骤:

步骤1/4)对main.c进行预处理以生成main.i:

$: gcc -E main.c -o main.i

步骤2/4)编译main.i以生成main.s:

$: gcc -S main.i -o main.s

步骤3/4)组装main.s生成main.o:

$: as main.s -o main.o

注意:您可以使用gcc的-c(小C)标志来组合上述步骤1、2和3:

$: gcc -c main.s -o main.o

步骤4/4)将main.o与其他必要的目标文件链接,即crti.o和crtn.o(分别定义函数prolog和Epilog),crt1.o(包含_start符号,用于引导初始执行)程序),libc.so路径或libc的-lc标志,然后最终设置动态链接程序的名称,以生成动态链接的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

或(如果您想指定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

在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

或(如果您想指定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.so.3 -o main_ELF_executable

然后您可以运行ELF可执行文件“ main_ELF_executable”:

$: ./main_ELF_executable
  

Hello World!

来源:

  

https://linux.die.net/man/1/gcc

     

https://linux.die.net/man/1/ld

     

https://dev.gentoo.org/~vapier/crt.txt

答案 4 :(得分:0)

您可以gcc在任何地方启动和停止编译过程。 gcc test.s -o test会将汇编中的test.s编译为可执行文件。

答案 5 :(得分:0)

正如您可能知道或不知道的那样,编译的四个阶段是预处理(-E),编译到汇编(-S),汇编到目标代码(-c),最后链接。我最难弄明白的是如何使用预处理器输出。这是如何做到的:

gcc -E hello.c | gcc -S -xc -o hello.s -
gcc -c hello.s -o hello.o
gcc hello.o -o hello