Live data from Hacker News

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

mymicrocontroller.com

91–100 of 104 posts

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

#91

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?)

Below is a sample "1.asm" source file which in one expt yields a 2.2K static binary.

"main" has been renamed to "xyz".

    format ELF
    section '.text' executable
    public xyz 

    extrn _exit
    extrn write

    xyz: 
    mov eax,len00
    push eax
    push char00
    mov eax,1
    push eax
    call write
    call _exit

    section '.data' writeable

    char00 db "21 symbols", 0xA 
    len00 = $ - char00

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

#92

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(…

Something surprising about C is that an empty argument list doesn't mean "no arguments", it means "unspecified arguments".

https://stackoverflow.com/questions/693788/is-it-better-to-u...

Though that is unlikely to be related to the arguments passed to main.

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

#93
post #64

Earlier quoted context omitted.

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…

Eh, on the M4s, they borked it. There's an errata that the floating point spill doesn't take into account the divide pipeline, so it can not wait enough time for the pipeline flush, and corrupt the register save. So you have to write your own asm interrupt prologue anyway. : /

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

#94

Earlier quoted context omitted.

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

That doesn't explain why you suggested a more expensive chip.

What's cheaper or not depends on your volume at that level.

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

#96

Earlier quoted context omitted.

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 conventio…

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

Like what?

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

#97

Earlier quoted context omitted.

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

Because you need a syscall to exit the process.

Is that not what this part of the code does?

  movl $1,%eax
  int $0x80

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

#98

Earlier quoted context omitted.

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 conventio…

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

On architectures like x86, the set of registers is limited and some are special, so there is some contention going on.

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

#99
post #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...

That sounds like Brooks Davis' talk that he has given at a few conferences:

https://www.youtube.com/watch?v=yWCMy5EiNkQ https://people.freebsd.org/~brooks/talks/eurobsdcon2016-hell...

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

#100

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?)

Below is a sample "1.asm" source file which in one expt yields a 2.2K static binary. "main" has been renamed to "xyz". format ELF section '.text' executable public xyz extrn _exit extrn write xyz: mov eax,len00 push eax push char00 mov eax,1 push eax call write call _exit section '.data' writeable char00 db "21 symbols", 0xA len00 = $ - char00

(1.3K stripped)
Post reply on HN