我如何以与 clang -c main.c 相同的方式从汇编源代码生成目标文件
How can i produce an object file from an assembler source in the same way as clang -c main.c does
我想研究 obj
文件的细节,我已经制作了一个 main.S
文件,当我使用 as main.S
时,我在 return 可以 运行 直接与 ./a.out
和 ld -m elf_x86_64 a.out
会产生错误。
我想生成一个目标文件,其文件类型与clang -c main.c
的结果相同。
我该怎么做?
可能是我操作错了,导致解释错误。 as
不生成可执行文件,可执行文件是clang的结果。感谢所有回答者,很抱歉造成混乱,浪费了你的时间。
最简单的方法,使用 clang -v -fno-integrated-as -c main.c
并从其输出中获取 gas 命令行。
as -o foo.o foo.s
如果你有一个 .S
,通常这意味着你想 运行 它在汇编之前通过 C 预处理器。 gcc
和 clang
前端将为您完成:gcc -c foo.S
(默认输出文件名 foo.o,而不是 a.out)。但是,如果您的 .S
实际上没有任何 CPP 指令,例如 #if
或 #define
,您可以 assemble 使用 as
.
a.out
是 as
输出的默认名称,但它 是 一个目标文件,就像您从 gcc -c foo.s
,不是 linked 可执行文件! GNU Binutils as
不生成 linked 可执行文件。
(ld foo.o
或 gcc
/ clang
没有 -c
的默认输出文件名是 also a.out,但不要被名字所迷惑。)
您可以使用 gcc -v -c foo.s
来显示它使用的 as
命令行,包括 -o
选项。 (clang 有一个内置的 assembler,所以它不会 运行 一个单独的 as
命令,但是 gcc
前端确实只是 运行 as
to assemble asm source files. And without -c
, then 运行s ld
(via collect2) to link the object file into一个可执行文件。)
例如在我的 x86-64 GNU/Linux 系统上:
$ cat > foo.s
mov 1, %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
...
我想研究 obj
文件的细节,我已经制作了一个 main.S
文件,当我使用 as main.S
时,我在 return 可以 运行 直接与 ./a.out
和 ld -m elf_x86_64 a.out
会产生错误。
我想生成一个目标文件,其文件类型与clang -c main.c
的结果相同。
我该怎么做?
可能是我操作错了,导致解释错误。 as
不生成可执行文件,可执行文件是clang的结果。感谢所有回答者,很抱歉造成混乱,浪费了你的时间。
最简单的方法,使用 clang -v -fno-integrated-as -c main.c
并从其输出中获取 gas 命令行。
as -o foo.o foo.s
如果你有一个 .S
,通常这意味着你想 运行 它在汇编之前通过 C 预处理器。 gcc
和 clang
前端将为您完成:gcc -c foo.S
(默认输出文件名 foo.o,而不是 a.out)。但是,如果您的 .S
实际上没有任何 CPP 指令,例如 #if
或 #define
,您可以 assemble 使用 as
.
a.out
是 as
输出的默认名称,但它 是 一个目标文件,就像您从 gcc -c foo.s
,不是 linked 可执行文件! GNU Binutils as
不生成 linked 可执行文件。
(ld foo.o
或 gcc
/ clang
没有 -c
的默认输出文件名是 also a.out,但不要被名字所迷惑。)
您可以使用 gcc -v -c foo.s
来显示它使用的 as
命令行,包括 -o
选项。 (clang 有一个内置的 assembler,所以它不会 运行 一个单独的 as
命令,但是 gcc
前端确实只是 运行 as
to assemble asm source files. And without -c
, then 运行s ld
(via collect2) to link the object file into一个可执行文件。)
例如在我的 x86-64 GNU/Linux 系统上:
$ cat > foo.s
mov 1, %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
...