assembly - 如何以与 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 的结果。感谢所有回答者,很抱歉造成混乱,浪费了您的时间。
解决方案
as -o foo.o foo.s
如果你有一个.S
,通常这意味着你想在组装之前通过 C 预处理器运行它。gcc
和clang
前端将为您执行此操作:(默认gcc -c foo.S
输出文件名 foo.o,而不是 a.out)。但是,如果您.S
实际上没有任何 CPP 指令,例如#if
or #define
,您可以将其与as
.
a.out
是 的输出的默认名称as
,但它是一个目标文件,就像您从中获得的一样gcc -c foo.s
,而不是链接的可执行文件! GNU Binutilsas
不生成链接的可执行文件。
(ld foo.o
or gcc
/ clang
without的默认输出文件名-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
...
推荐阅读
- spring-boot - Spring Boot - 没有数据库调用的 JWT 身份验证
- r - h2o target_encode_apply kfold 生成重复项
- c# - StackExchange.Redis.RedisTimeoutException - 由于 qs 人们如何解决它?
- rest - 以编程方式定义 @DeclareRoles 注释
- typescript - 在 Typescript 中创建使用与超集类型相同的道具的更复杂类型时,如何避免代码重复?
- java - 为什么找不到这些符号?
- amazon-web-services - 无法在需要基本身份验证的页面上使用 AWS S3 对象
- html - CSS 在 URL 中使用波浪号作为具有未知完整 URL 的文件夹名称的一部分
- css - Google recaptcha 样式问题,用 css 还是 javascript 解决?
- java - 如果输入了无效选项,我如何循环代码