Live data from Hacker News

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

mymicrocontroller.com

81–90 of 104 posts

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

#81

Earlier quoted context omitted.

Have you read "The Amazing $1 Microcontroller" [0], which might have been posted here before? It's a survey of available microcontrollers, with the intent of helping you choose one. If you have read it, are you in agreement with the article, for example on how AVRs compare to others? [0] https://jaycarlson.net/microcontrollers/

Yeah, he put a lot of work into that, and I love that he published all of the information. My biggest complaint though is that he expresses GPIO cycle time and interrupt latency in cycles, rather than normalized on real time. Particularly when comparing a STM32F0 to an AVR, the perf looks almost even, until you realize that the STM32F0 is clocked 2.5x faster.

Good point. Have you, or someone else, mentioned this to the author?

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

#82

Earlier quoted context omitted.

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

I can't find any 8051 less than 30 cents and I digikey sells attinys for 17 cents.

> digikey

There's your problem. Digikey is only really meant for low volume.

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

#83
This is a misleading headline for the general audience.

What he writes is an introduction to bare metal programs for somebody who has worked under an operating system before.

In both cases a lot of code is run before main(). But very different code. In bare metal you more likely need to care what it does. In the operating system case the developers of the OS more likely have done more for you than you will ever need to know about.

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

#84
post #83

This is a misleading headline for the general audience. What he writes is an introduction to bare metal programs for somebody who has worked under an operating system before. In both cases a lot of code is run before main(). But very different code. In bare metal you more likely need to care what it does. In the operating system case the developers of the OS more likely have done more for you than you will ever need…

A couple of years ago there was a conference presentation (FOSDEM?) about what a program does before reaching main(). The presenter (a Brit IIRC) went pretty fast, did not go into too much detail and it took him 30-40 minutes. I think the study was done on a BSD. Maybe somebody can provide a link, the video is online, but Google resists to help me...

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

#86

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.

On Windows this dependes on the calling convention. The calling convention determines whether function arguments are passed: In order or in reverse order. Who takes care of cleaning the stack: caller or callee? And even if the arguments are passed by stack or CPU registers.

In Visual Studio you can control this behavoir with the __cdecl, __clrcall, __stdcall, __fastcall, __thiscall, __vectorcall [1] calling convention function prefixes, but this also depends on the optimization options [2] of the compiler.

Passing arguments via CPU registers has a huge preformance benefit, but also some drawbacks.

[1]: https://msdn.microsoft.com/en-us/library/984x0h58.aspx

[2]: https://msdn.microsoft.com/en-us/library/46t77ak2.aspx

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

#87

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?

Because you need a syscall to exit the process.

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

#88
post #62
post #60

Earlier quoted context omitted.

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.

It shouldn’t work on amd64 because the x64 calling convention puts the arguments in the registers first

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

#89
post #64

Earlier quoted context omitted.

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.

Yes, exactly this. As someone who has written startup code in many flavors of assembly (PIC, ARMv4, MIPS, PowerPC, AVR...), I appreciated what ARM did with the design of the Cortex-M architecture -- they designed it so that you could write fully-functional embedded software (firmware) without a line of assembly.

Normally, the 2 places you can't avoid assembly are (1) the startup code (because you're doing things like disabling interrrupts and setting the stack pointer) and (2) interrupt service routines - usually there is a little bit of magic on the front and back ends (for example on an older ARM7 chip, the CPU didn't automatically push / save any registers onto the stack, you had to do it yourself if you needed that).

With the Cortex-M, the CPU design and its microcode took care of all that, so all of the messy assembly stuff went away. Now, as someone who started writing 6502 ASM as a kid, I kind of miss it, but as someone who has to build lots of systems and ship products on deadlines, I like the change.

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

#90

Earlier quoted context omitted.

I can't find any 8051 less than 30 cents and I digikey sells attinys for 17 cents.

> digikey There's your problem. Digikey is only really meant for low volume.

That doesn't explain why you suggested a more expensive chip.
Post reply on HN