title: Is Intel's timestamp reading asm code example using two more registers than are necessary?
body: <p>I'm looking into measuring benchmark performance using the time-stamp register (TSR) found in x86 CPUs. It's a useful register, since it measures in a monotonic unit of time which is immune to the clock
  speed changing. Very cool.</p>
  
  <p>Here is an Intel document showing asm snippets for reliably benchmarking using the TSR, including using cpuid for pipeline synchronisation. See page 16:</p>
  
  <p><a href="http://www.intel.com/content/www/us/en/embedded/training/ia-32-ia-64-benchmark-code-execution-paper.html" rel="noreferrer">http://www.intel.com/content/www/us/en/embedded/training/ia-32-ia-64-benchmark-code-execution-paper.html</a></p>
  
  <p>To read the start time, it says (I annotated a bit):</p>
  
  <pre><code>__asm volatile (
      "cpuid\n\t"             // writes e[abcd]x
      "rdtsc\n\t"             // writes edx, eax
      "mov %%edx, %0\n\t" 
      "mov %%eax, %1\n\t"
      //
      :"=r" (cycles_high), "=r" (cycles_low)  // outputs
      :                                       // inputs
      :"%rax", "%rbx", "%rcx", "%rdx");       // clobber
  </code></pre>
  
  <p>I'm wondering why scratch registers are used to take the values of <code>edx</code>
  and <code>eax</code>. Why not remove the movs and read the TSR value right out of <code>edx</code>
  and <code>eax</code>? Like this:</p>
  
  <pre><code>__asm volatile(                                                             
      "cpuid\n\t"
      "rdtsc\n\t"
      //
      : "=d" (cycles_high), "=a" (cycles_low) // outputs
      :                                       // inputs
      : "%rbx", "%rcx");                      // clobber     
  </code></pre>
  
  <p>By doing this, you save two registers, reducing the likelihood of the C
  compiler needing to spill.</p>
  
  <p>Am I right? Or those MOVs are somehow strategic?</p>
  
  <p>(I agree that you do need scratch registers to read the <em>stop</em> time, as
  in that scenario the order of the instructions is reversed: you have
  rdtscp, ..., cpuid. The cpuid instruction destroys the result of rdtscp).</p>
  
  <p>Thanks</p>