首页 > 解决方案 > 如何以与 clang -c main.c 相同的方式从汇编程序源生成目标文件

问题描述

我想研究一个obj文件的细节,我已经生成了一个main.S文件,当我使用时as main.S我得到一个a.out文件作为回报,它可以直接运行./a.out并且ld -m elf_x86_64 a.out会产生错误。

我想生成一个文件类型与结果相同的目标文件clang -c main.c。我怎样才能做到这一点?


我可能混淆了操作,从而导致了错误的解释。as不产生可执行文件,可执行文件是 clang 的结果。感谢所有回答者,很抱歉造成混乱,浪费了您的时间。

标签: assemblygnu-assembler

解决方案


as -o foo.o foo.s

如果你有一个.S,通常这意味着你想在组装之前通过 C 预处理器运行它。gccclang前端将为您执行此操作:(默认gcc -c foo.S输出文件名 foo.o,而不是 a.out)。但是,如果您.S实际上没有任何 CPP 指令,例如#ifor #define,您可以将其与as.


a.out是 的输出的默认名称as,但它一个目标文件,就像您从中获得的一样gcc -c foo.s,而不是链接的可执行文件! GNU Binutilsas不生成链接的可执行文件。

ld foo.oor gcc/ clangwithout的默认输出文件名-c也是a.out,但不要被名称所迷惑。

您可以使用它gcc -v -c foo.s来显示as它使用的命令行,包括-o选项。(clang 有一个内置的汇编器,所以它不会运行单独的as命令,但gcc前端确实只是运行as来汇编 asm 源文件。没有-c, 然后运行ld(通过 collect2)将目标文件链接到可执行。)

例如在我的 x86-64 GNU/Linux 系统上:

$ cat > foo.s
mov $231, %eax             # __NR_exit_group
syscall
$ as foo.s
$ file a.out
a.out: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
$ ld a.out -o exit
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
$ ls -l exit a.out 
-rw-r--r-- 1 peter peter  664 Mar 22 08:23 a.out
-rwxr-xr-x 1 peter peter 4632 Mar 22 08:23 exit
$ file exit
exit: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

$ ./a.out
bash: ./a.out: Permission denied
$ ./exit
$ strace ./exit 
execve("./exit", ["./exit"], 0x7ffc72823fc0 /* 55 vars */) = 0
exit_group(0)                           = ?
+++ exited with 0 +++
$ as --version
GNU assembler (GNU Binutils) 2.35.1
...
This assembler was configured for a target of `x86_64-pc-linux-gnu'.
$ ld --version
GNU ld (GNU Binutils) 2.35.1
...

推荐阅读