I used to get a similar error, but it didn't tell me which file it couldn't find. Just "bash: no such file or directory". Quite confusing, since my "program" was right there. Examination of the executable (just a text editor) showed the text "/lib/ld-linux.so.1" which does not exist. The "--dynamic-linker" switch has a shorter alias "-I" (Interpreter). Telling ld "-I /lib/ld-linux.so.2" solved it for me. Sounds like your setup may need "/usr" in there, as well, but probably something similar.
I'm told, but never tried it, that you can fix it by changing a line in a configuration file and rebuilding ld. It's part of the "binutils" package, not the "gcc" package. I don't know why it still defaults to a filename that apparently hasn't been used for quite a while. Balkward compatibility?
I would have expected, as Rob says, that we need that "startup code" if we're going to use the library routines. To my surprise, this seems not to be true. At the cost of typing a lengthy command line to ld, I seem to be able to use the libraries without the "startup code". There may be some massive bug waiting to bite me, but so far it "seems to work".
The flip side of this is that it doesn't cost much to let gcc link in "crt?.o", even if we don't actually need it. A couple of k, as I recall. No big deal. In return, gcc "knows where the bodies are buried" and knows how to tell ld what it wants, so we don't have to figure it out.
The "main" thing the startup code does for us is "call main". It contains the "_start" label. The _start label was not called, so there's no return address on the stack. The first thing on the stack is the argument count (always at least 1, the program name). Then, working up the stack, is a zero-terminated array of pointers to zero-terminated strings - your command line arguments. Then there's a zero-terminated array of pointers to environment variables (also zero-terminated strings) - no count of these. When "main" gets control, there's a return address, argc, and pointers to arrays of arguments and environment variables. There's an extra dereference involved to get at the stuff. There may be other things the startup code does for us, but that's what I know of that we need to be aware of. Source code is available, if you care enough.
We do need that interpreter/dynamic loader to use the libraries. If you "strace myprog" you can see it opening files and mmapping them like crazy. It's a busy little beaver before it gets to your code. In contrast, if you stick to system calls, your code gets executed right away. To get a float, it's worth the detour!
Best,
Frank