High level languages like C do not expose all functionality of the CPU's instruction set. Sometimes the compiler is smart enough to use those features without being told to, but sometimes hoping for the best is not an option – you need to write a bit of assembly.
There are three typical ways to do this:
- The compiler might offer intrinsics, pseudo-functions that the compiler will translate to an assembly instruction. The resulting code looks like C, but you need some knowledge of the instruction set to use them properly.
- inline assembly
- separate assembly files that are linked later
In most cases these assembly snippets are motivated by having access to special assembly instructions (e.g.
syscall, or instructions related to interrupts). This kind of code is typically found in kernels or in standard libraries. In some cases assembly code is used for extremely performance-sensitive code paths, where it is not OK to depend on compiler optimizations. E.g. some language runtimes use assembly snippets for critical functionality like method dispatch. In particular for crypto code, it might also be desirable to prevent any compiler optimizations as they could make the implementation vulnerable to timing attacks.