gcc -c
would run the compiler proper (some cc1
) which produces assembly code, then the assembler (as
). Check with gcc -v -c
to understand what exactly is happening.
The compiler (actually cc1
) is translating your C code into assembly code.
Then the assembler (as
) is translating that assembly code into an object file (in Executable & Linkable Format, a.k.a. ELF).
An ELF object file contains segments of bytes (e.g. code or .text
segment or .data
segment) with relocation instructions or directives and defines (& uses) symbolic references. Relocation is processor dependent, see e.g. this list of relocation types and the x86-64 ABI spec - for application binary interface. These relocations are processed by the linker (ld
, started by gcc
). Read Levine's Linkers and loaders book. So ELF object files contain bytes with relocation instructions and symbol tables.
The linker would modify some machine instructions (or other data) according to relocation codes.