如果使用gcc编译,并且链接了C的标准库(crti.o, crt1.o以及libc等),那么此时和编译普通的C程序一样,需要提供一个main的符号。(crt1.o里面有_start,_start会调用__libc_start_main,再调用main)。例如:
1 | # example.s |
通过1
gcc example.s -o example
编译即可。如果编译遇到了类似relocation R_X86_64_32S against '.text' can not be used when making a shared object; recompile with -fPIC
的错误,可以给gcc加个-static
参数,或者按照这里的说明,添加-no-pie
参数。
或者也可以:1
as example.s -o example.o && ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/crtn.o -lc example.o -o example
当然crt那些文件的路径可能会有些差异。
如果你不需要链接libc,只需要把main
改成_start
,然后这样编译:
1 | gcc -nostdlib example.s -o example |
,或者分成两步:1
as example.s -o example.o && ld example.o -o example
此时对生成的文件执行ldd,会提示不是一个动态链接的可执行文件。
当然构造给execve()的argv参数,也可以放到数据区:
1 | # example.s |