C does not abstract away from OS. C tries to stay away from machine dependent details, but it does not abstract away from hardware. You have full control of register, memories, interrupts etc. using C. The compiler does not know how to set up timers, or use DMA. You always need to know your hardware. And you have full, and only, control of it using C.
It does abstract on big computers. It used to be a lot of different processors that UNIX could run on. You write a single program on C and you can compile it for any of them. And now you can compile it and run on my phone, even though the phone, and ARM processors, didn't even exist when the program was written. Or on Windows. Or a future system that doesn't even exist now. That's what it was created for.
Now, like you said, it doesn't really matter on MCU because you hard-code your register, memories, interrupts, DMA into your code. Once you do that, it is no longer portable.
Complex data structure is equally complex with asm.. what would change that. It is in your hands to design the datastructure you need. Data is data.. Using C does not mean you are automatically using heap memory and fragmenting everything. I rarely use heap memory. And C does not allocate heap memory. It is up to the programmer how he uses memory.
Right. C is very good with complex data structures. You can allocate structures, interlink them, walk through them. But, to allocate them you need a heap. For example, you need to build a binary tree with elements of varying size. You cannot do that without a heap. It is not practical on MCU, so you don't use it. Another advantage of C is lost.
No wonder people have problems with pointers. Without a heap, they don't have anything for the pointers to point to.
"Big" programming does not mean you need "big" memory. It means you are doing "big" things. Complex things. Things that makes your head spin fast unless you choose the right tool for the job.. write modular code, get organized.
"Big" things that make you head spin do not really depend on the choice of language. You design it, then you break it in pieces, then you code them. I don't really like coding per se. After the design is done, it becomes a chore.
Sounds like you think that the Assembler code is inherently disorganized. That is not true. It depends on programming habits. One can write a very messy code in C, or one can write beatiful code in Assembler. These are just different ways to write programs. There are also compilers for Pascal, or for Basic.
MCU resources are limited, so whatever language you choose to use will not be a limitation (as it would be the case if I wanted to write an Assembler program for Windows). You choose what you feel is the best. I feel that for me, for writing a program for 16-bit PICs, Assembler is the best choice. That is not because I want to spend more time programming in Assembler, but because I want to do it as quickly and painlessly as possible. If MCUs get more powerful then the situation may change.
"C is not far from asm really. It is just more productive way to code it. I would even bet that most C compilers produce better ASM than average hobby asm coder.
Not far at all. It is just a different way to write the same thing. It is a good thing that there's a variety of languages to use.