as -o foo.o foo.s
If you have a .S
, normally that means you want to run it through the C preprocessor before assembling. The gcc
and clang
front-ends will do that for you: gcc -c foo.S
(default output filename foo.o, instead of a.out). If your .S
doesn't actually have any CPP directives like #if
or #define
, though, you can just assemble it with as
.
a.out
is the default name for the output of as
, but it is an object file like you'd get from gcc -c foo.s
, not a linked executable! GNU Binutils as
does not produce linked executables.
(The default output filename for ld foo.o
or gcc
/ clang
without -c
is also a.out, but don't be fooled by the name.)
You can use gcc -v -c foo.s
to show the as
command line it uses, including the -o
option. (clang has a built-in assembler, so it won't run a separate as
command, but the gcc
front-end truly does just run as
to assemble asm source files. And without -c
, then runs ld
(via collect2) to link the object file into an executable.)
e.g. on my x86-64 GNU/Linux system:
$ 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
...