3

Is there anything that we can do in assembly that we can't do in raw C? Or anything which is easier to do in assembly? Is any modern code actually written using inline assembly, or is it simply implemented as a legacy or educational feature?

sig_seg_v
  • 570
  • 4
  • 15
  • I can see an analogy between embedding inline assembly in C++ and using the JNI to embed C code in Java: each calls code from a lower level of abstraction inside code from a higher level. I used the JNI to embed code that called the OpenSL-ES bindings to play audio on an android without going through the android java API; I wonder if there are similar uses for inline assembly? – sig_seg_v Jan 25 '15 at 16:31
  • 5
    reasons to use inline assembly? here are afew: 1) when the coder wants to use the intrinsic instructions 2) when speed of small loops is paramount 3) when bit-fiddling memory mapped peripheral registers where reading/writing a register affect different operations on the the peripheral. 4) when implementing an I/O protocol via 'bare' gpio bits and timing of bit transitions is important 5) when coding interrupt handler entry/exit code blocks that need to be different than what the C compiler would produce. Just to name a few instances where assembly code is preferred over C – user3629249 Jan 25 '15 at 16:43
  • 1
    Besides that of @user3629249: When you want to interface between several languages with different calling conventions; to call OS services directly; to call firmware services directly; to implement coroutine-like code... – rodrigo Jan 25 '15 at 16:46
  • There are many valid uses of asm, as others have pointed out. The use of `intrinsics` is a middle ground, you can use machine specific instructions and still allow the compiler to allocate registers and do optimizations, for Intel an essential guide to intrinsics is here https://software.intel.com/sites/landingpage/IntrinsicsGuide/ – amdn Jan 25 '15 at 18:01
  • How do you get a program to start at `main`? That's not necessarily a justification for assembly, but you can follow the chain - how does a kernel set up an entry point? How is a CPU interrupt handled? How does a context switch happen in a modern OS? – Brett Hale Jan 25 '15 at 18:07

2 Answers2

6

Inline assembly (and on a related note, calling external functions written purely in assembly) can be extremely useful or absolutely essential for reasons such as writing device drivers, direct access to hardware or processor capabilities not defined in the language, hardware-supported parallel processing (as opposed to multi-threading) such as CUDA, interfacing with FPGAs, performance, etc.

It is also important because some things are only possible by going "beneath" the level of abstraction provided by the Standard (both C++ and C).

The Standard(s) recognize that some things will be inherently implementation-defined, and allow for that throughout the Standard. One of these allowances (perhaps the lowest-level) is recognition of asm. Well, "sort of" recognition:

In C (N1256), it is found in the Standard under "Common extensions":

J.5.10 The asm keyword
1 The asm keyword may be used to insert assembly language directly into the translator output (6.8). The most common implementation is via a statement of the form:

asm ( character-string-literal );

In C++ (N3337), it has similar caveats:

§7.4/1
An asm declaration has the form

asm-definition:

asm ( string-literal ) ;

The asm declaration is conditionally-supported; its meaning is implementation-defined. [ Note: Typically it is used to pass information through the implementation to an assembler. —end note]

It should be noted that an important development in recent years is that attempting to increase performance by using inline assembly is often counter-productive, unless you know exactly what you are doing. Compiler/optimizer register usage decisions, awareness of pipeline and branch prediction behavior, etc., are almost always enough for most uses.

On the other hand, processors in recent years have added CPU-level support for higher-level operations (such as Intel's AES extensions) that can increase performance by several orders of magnitude for specialized applications.

So:

Legacy feature? Not at all. It is absolutely essential for some requirements.

Educational feature? In an ideal world, only if accompanied by a series of lectures explaining why you'll probably never need it, and if you ever do need it, how to limit it's visible surface area to the rest of your application as much as possible.

Community
  • 1
  • 1
frasnian
  • 1,973
  • 1
  • 14
  • 24
5

You also need to code with inlined asm when:

  • you need to use some processor features not usable in standard C; typically, the add with carry machine instruction is useful in bignum implementations like GMPlib

  • on today's processors with current optimizing compilers, you usually should not use  asm for performance reasons, since compilers optimize better than you can (an old example was implementing memcpy with rep stosw on x86).

  • you need some asm when you are using or implementing a different ABI. For example, the runtime system of some Ocaml or Common Lisp implementations have different calling conventions, and transitioning to them may require asm; but the current libffi (which is using  asm) may avoid you to code with asm

  • your brand-new hardware might have a recent instruction set not fully implemented by your compiler (e.g. extensions like AVX512...) for which you might need asm

  • you want to implement some functionality not implementable in C, e.g. backtrace

In general, you should think more than twice before using asm and if you do use it, you should use it in very few places. In general, avoid using asm....

The GCC compiler introduced an extended asm feature which has nearly become a de facto standard supported by many other compilers (e.g. Clang/LLVM...) - but the evil is in the details. See also the GCC Inline Assembly HowTo

The Linux kernel (and the many libc implementations, e.g. glibc or musl libc, etc...) is using asm (at least to make syscalls) but few major free software are also (directly) using asm instructions.

Read also the Linux Assembly HowTo

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547