如果你有一个简单的C程序,比如
int main(void) {return 0;}
可以使用gcc -o test test.c
编译。
据我所知,gcc执行编译,汇编然后链接。后两个步骤是通过运行as
和ld
来实现的。
我可以使用gcc -S test.c
生成汇编代码。
您要在终端中输入什么内容,将汇编代码转换为可执行文件?
(这样做的原因是学习装配)
答案 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
答案 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