I've written code for GameBoy Advance which has no OS, just magic memory addresses, and didn't need any assembly. Even hblank interrupts could be implemented in C.
A typical reason to use assembly these days is for instructions the compiler doesn't output (for instance specialized instructions which are only useful for a kernel).
GCC's extended assembly at least (which clang/LLVM also support), allows one to specify constraints for asm() statements that let the compiler respect dependencies etc.