I see a huge semantic gap between assembly language and C.
An assembly language program specifies a sequence of CPU instructions. The mapping between lines of code and generated instructions is one-to-one, or nearly so.
A C program specifies run-time behavior, without regard to what CPU instructions might be used to achieve that.
C is at a lower level than a lot of other languages, but it's not an assembly language.
And yet modern assembly does not correspond 1:1 to the micro-ops the CPU runs or even necessarily the order in which they run.
Both ISA-level assembly and C are targeting an abstract machine model, even if the former is somewhat further removed from hardware reality.