Live data from Hacker News

What happens before main() is executed in C and why is it important?

mymicrocontroller.com

61–70 of 104 posts

Re: What happens before main() is executed in C and why is it important?

#61
I am a neophyte x86 asm user.

I link using gcc and -nostdlib plus a very simple start.S:

   .globl _start
   _start:
   call main
   movl $1,%eax
   xorl %ebx,%ebx
   int $0x80
fasm 1.asm;gcc -nostdlib start.S 1.o lib1.a;a.out

"lib1.a" contains only the functions needed by a.out instead of, e.g., every function in libc.a

I use ar -M (Did I forget about crt0.o?)

Re: What happens before main() is executed in C and why is it important?

#62
post #60

To me one curious thing about the main() function without arguments is, these arguments are still pushed onto the stack. You can find them by dereferencing a pointer of another stack variable and playing around with the offset. // Just tested with mingw-gcc on Win8.1 // Maybe you need to play around with the offset, +28 int main() { int i; // Another stack variable printf("%d\n", (long long)&i + 28); // &argv printf(…

totally unportable and undefined behavior

I have strong feeling that while this obviously works on i386 linux (and probably any unix for that matter) if it works on even amd64 it's just a pure coincidence.

Re: What happens before main() is executed in C and why is it important?

#63

Earlier quoted context omitted.

I guess I rarely see the case for an AVR when you're not prototyping on an Arduino. You can get chips that are an order of magnitude more powerful per $/watt/and any other metric you'd want to use.

Low latency IO and computational performance isn't always needed.

If it's not, you can drop the cost. There are AVR like 8051s that you can get for 10 cents.

Re: What happens before main() is executed in C and why is it important?

#64
post #51

Earlier quoted context omitted.

You can't really initialize the stack pointer in a constructor, or indeed in C++ at all; there's no syntax for it and the compiler may use the stack to allocate local variables in the function prologue.

You can if you're super duper careful and throw in a little inline asm, depending on the architecture. ARM for instance is very likely not to need to spill to the stack on tiny little leaf functions. It's an absolutely terrible idea, but I've seen engineers be so afraid of asm files that they'd try something like this.

The ARM Cortex-M series of chips is I believe kind enough to initialize the stack pointer for you before your code even executes, by copying your chosen stack pointer value from a special reserved location in the interrupt vector table. So in principle you could write all your hardware init code in C.

Re: What happens before main() is executed in C and why is it important?

#66

> Command line arguments are received. Nit: that’s not the best wording. if the executable is being executed by something like `exec` then these are just “arguments”; the command line (i.e. a shell) isn’t involved. Do embedded systems support something like `exec`?

They're still called command-line arguments out of convention: https://en.wikipedia.org/wiki/Command-line_interface#Argumen...

Re: What happens before main() is executed in C and why is it important?

#67

I am a neophyte x86 asm user. I link using gcc and -nostdlib plus a very simple start.S: .globl _start _start: call main movl $1,%eax xorl %ebx,%ebx int $0x80 fasm 1.asm;gcc -nostdlib start.S 1.o lib1.a;a.out "lib1.a" contains only the functions needed by a.out instead of, e.g., every function in libc.a I use ar -M (Did I forget about crt0.o?)

Why even have the overhead of a function call to main in that case?

Re: What happens before main() is executed in C and why is it important?

#68

There articles are so incomplete and always make it to the top on HN... I need some explanation.

It's not hard to take a look at doing this yourself: just run a program, break at main, and check what's in your stack backtrace.

Re: What happens before main() is executed in C and why is it important?

#69
post #14

Personally, I think global's with constructors are kind of an anti pattern. I've noticed a high correlation between crappy app's and app's with a lot of pre main() code. Especially if some of your global's have threads: because then you potentially have threads running AFTER main exits... I've seen a number of apps with random crashes at shutdown because a thread that was started in a global was still running and sin…

> some of your global's have threads

Creating threads in pre-main code is generally a code smell, rather than running pre-main code.

Re: What happens before main() is executed in C and why is it important?

#70

To me one curious thing about the main() function without arguments is, these arguments are still pushed onto the stack. You can find them by dereferencing a pointer of another stack variable and playing around with the offset. // Just tested with mingw-gcc on Win8.1 // Maybe you need to play around with the offset, +28 int main() { int i; // Another stack variable printf("%d\n", (long long)&i + 28); // &argv printf(…

Here's what works on my Mac, compiled with clang -m32.

  #include 
  
  int main() {
  	int i;                                // Another stack variable
  	printf("%s\n", **(char ***)(&i + 8)); // argv[0]
  	return 0;
  }
Of course, this won't work at all on x86_64 because arguments are passed on registers instead of the stack.
Post reply on HN