Linus Torvalds: “when I read C I know what the output Assembly is going to look like.”
That's exactly the attraction of assembler, assembler being a somewhat symbolic representation of the CPU/architecture you're working with that translates pretty directly into machine instructions (easy enough to understand if you run the debugger). And straight up machine code is a PITA to write.
So... if you're writing 'portable' code, it's pretty easy to hand things back and forth between C and whatever you write in assembler for a particular machine. How? Mostly via stack framing. You can also violate framing, but I promise that this will eventually bite you.
I've done similar with C++, but only to hand optimize 'hotspots'.