Channels ▼

Walter Bright

Dr. Dobb's Bloggers

Inline Assembler for Über Nerds

July 21, 2011

Inline assembler (IA) is the practice of embedding assembly language instructions in a high-level programming language's source code, and is an early example of an EDSL (Embedded Domain Specific Language).

IA isn't needed that often if the host programming language is powerful, but it is used to:

  1. Generate special instructions, like locking code for multithreaded synchronization
  2. Access special CPU features, such as debug registers
  3. Super optimize a very critical section of code
  4. Ease into learning assembler
  5. Be an intermediate step when translating large assembly language projects into a high-level language
  6. Build thunks or access code that has special calling conventions
  7. Interface to hardware requiring specific instruction sequences to access

Add a special point 8 for me, as I get an endorphin rush from writing a particularly crafty bit of assembler. Yes, I am a nerd.

Look over the source to an operating system or a device driver, and you're likely to find a sprinkling of inline assembler here and there.

Here's a simple example of inline assembler in the D programming language to use the Intel RDTSC instruction to read the clock count into the EDX and EAX registers:

long clock()
{
   asm
   {
     RDTSC;
   }
}

Long's are returned in EDX and EAX, so this works out famously. Here's a somewhat longer example to compute the tangent of x using the FPU instructions:

real tan(real x)
{
  asm
  {
    fld     x[EBP]   ; // load x
    fxam             ; // test for oddball values
    fstsw   AX       ;
    sahf             ;
    jc      trigerr  ; // x is NAN, infinity, or empty
                       // 387's can handle denormals
SC18:
    fptan            ;
    fstp    ST(0)    ; // dump X, which is always 1
    fstsw   AX       ;
    sahf             ;
    jnp     Lret     ; // C2 = 1 (x is out of range)
    // Do argument reduction to bring x into range
    fldpi            ;
    fxch             ;
SC17:
    fprem1           ;
    fstsw   AX       ;
    sahf             ;
    jp      SC17     ;
    fstp    ST(1)    ; // remove pi from stack
    jmp     SC18     ;
  }
trigerr:
  return real.nan;
Lret:
  ;
}

Despite thousands of different programming languages, only a relative handful support inline assembler. Surprisingly, even C and C++ don't officially have inline assemblers — they are done as extensions by compiler vendors. A C and C++ compiler can be 100% standard compliant with no inline assembler, and these do exist, such as Microsoft VC++ for Win64. I'm a bit old school: A language that calls itself a systems programming language ought to support an inline assembler.

The D programming language specifies that an inline assembler must be supported.

Some suggest that inline assemblers are obsolete; if one really needs an assembler, just use a separate assembler. There are lots of great assemblers out there. Why not?

I abandoned using separate assemblers years ago for the following reasons:

  1. Poor (i.e. zero) integration with the compiler.

  2. You have to rewrite your data structure and manifest constant declarations in the assembler, and of course these always get out of sync with the ones in your D source.

  3. Having the compiler set up the call/return sequences and parameter addressing is so darned convenient.

  4. The compiler will keep track of register usage for you — which registers are read or written — smoothly integrating with the code generator's usage of registers.

  5. There are lots of third-party assemblers, all different. Even the same assembler will have multiple versions. The chances of the asm source assembling on all of them, and avoiding all the various bugs, are zero. It is a major tech support issue.

  6. It really hurts my brain to have gas (Gnu ASsembler) swap the order of the operands.

  7. gas doesn't follow the Intel syntax, so you have to do a mental translation from the Intel datasheets to the gas source. gas doesn't even use the same instruction names.

  8. External assemblers don't do name mangling. You've got to do it all manually. This is a horror.

  9. Symbolic debug formats differ.

  10. Having to manage a separate source file for just two instructions is highly annoying.

  11. Writing an inline assembler isn't hard. There's nothing terribly clever about it.

Getting the assembler integrated into the compiler made me much more productive and my life much easier. It was a giant win for this nerd, no doubt about it. You can pry my inline assembler from my cold, dead fingers.

Thanks to Andrei Alexandrescu, Bartosz Milewski, and David Held for their helpful comments on a draft of this post.

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 


Video