Virtually no undefined behavior, but few security issues in C is because of compiler bugs or backdoors. And integer overflows, buffer overflows, and race conditions don't need any undefined behavior in C, and are the same problem in assembly.
But many programmer mistakes that a C compiler would at the very least warn about will only be apparent at runtime in assembly: Treating something as the wrong type, forgetting to dereference a pointer (or accidentally dereferencing it), mixing up values of different types, mutating something that's meant to be constant in a context, assigning an integer quantity to a pointer without an explicit cast...
Then on top of that you get a myriad of new potential mistakes that are impossible or at least very unlikely in C: Mixing up registers, accessing the wrong offset in a structure (e.g. easier to mix up reg+12 and reg+14 than foo.enabled and foo.name), messing up the stack layout... And now think about what each of those mean when you're actually changing code: Did you update every register? Did you update every offset?
As for the simpler code being simpler to understand and simpler to keep bug-free, that's kind of a tautology that applies independently of the language. And besides, wouldn't those qualities be even easier to achieve for the same code written in C?
But many programmer mistakes that a C compiler would at the very least warn about will only be apparent at runtime in assembly: Treating something as the wrong type, forgetting to dereference a pointer (or accidentally dereferencing it), mixing up values of different types, mutating something that's meant to be constant in a context, assigning an integer quantity to a pointer without an explicit cast...
Then on top of that you get a myriad of new potential mistakes that are impossible or at least very unlikely in C: Mixing up registers, accessing the wrong offset in a structure (e.g. easier to mix up reg+12 and reg+14 than foo.enabled and foo.name), messing up the stack layout... And now think about what each of those mean when you're actually changing code: Did you update every register? Did you update every offset?
As for the simpler code being simpler to understand and simpler to keep bug-free, that's kind of a tautology that applies independently of the language. And besides, wouldn't those qualities be even easier to achieve for the same code written in C?