0

Let's say I have the following C program:

// hi.c
int main() {
    int a = 8;
    int b = 13;
    return a + b;
}

On linux (x86_64 GNU/Linux), here is how I normally compile and run it:

ubuntu@ip-172-30-1:~/asm$ gcc ./hi.c
ubuntu@ip-172-30-1:~/asm$ ./a.out
ubuntu@ip-172-30-1:~/asm$ echo $?
21

However, I'm having a bit of trouble first compiling it to assembly and then running that. What I am trying now is:

$ gcc -S hi.c
$ head -n 5 hi.s
  .file "hi.c"
  .text
  .globl    main
  .type main, @function
 main:
$ as hi.s -o hi.out
$ ld hi.out -e main -o hi
$ ./hi
Segmentation fault (core dumped)

What am I doing incorrect with assembling/linking/running?

David542
  • 104,438
  • 178
  • 489
  • 842
  • You can't `ret` from the entry point, normally called `_start`. `main` is a function that tries to return, and doesn't work as the process entry point, `_start` isn't even a function. – Peter Cordes Jul 29 '20 at 22:04
  • 1
    The entry point of a typical hosted program is not `main` but something in the startup code from the runtime library (such as `_start` in `crt0.o`) – Eugene Sh. Jul 29 '20 at 22:05
  • 4
    Rin `gcc -v hi.c`. Observe what happens. – n. m. could be an AI Jul 29 '20 at 22:06
  • Normally `_start` comes from CRT startup code provided by libc, which gcc links with by default (https://web.archive.org/web/20191210114310/http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html), as explained in [What happens before main in C++?](https://stackoverflow.com/q/53570678) – Peter Cordes Jul 29 '20 at 22:09
  • @PeterCordes I see. So how would I go from C -> asm -> executable -> run? Is there something like `gcc -S` that can retain context details as well? – David542 Jul 29 '20 at 22:14
  • 1
    `gcc -S foo.c` && `gcc foo.s` to assemble + link normally. Like n. said, use `gcc -v` to see what that passes to the linker if you're curious. There's also `gcc -save-temps` to save the asm (and other temporaries) without stopping there. If that's what you wanted to ask, it's a duplicate of [How do I compile the asm generated by GCC?](https://stackoverflow.com/q/7190050) – Peter Cordes Jul 29 '20 at 22:15
  • @PeterCordes -- `$ gcc -v -s file` was very helpful to run. Two questions here: is `-s` the same as `-S` (capital vs lowercase)? And where is the "linking" done in the gcc commands? I tried doing a find for the terms but couldn't find anything. – David542 Jul 29 '20 at 22:32
  • `.s` and `.S` file extensions are related. GCC's `-s` option (`strip` the output binary) is totally unrelated to anything, IDK why you brought it up. Linking is necessary to turn a `.o` object file into an executable, filling in relocation entries and nailing down the position of sections in process address space (at least relative to each other, or absolute for non-PIE). – Peter Cordes Jul 29 '20 at 23:06

0 Answers0