title: Copy N unsigned int[] into char[] with N assembly instructions
body: <p>I am starting a Sudoku program and am experimenting with efficiently copying an <code>unsigned int[]</code> into a <code>char[]</code> while viewing the resulting AT&amp;T x86-64 assembly <strong>objdump -d</strong> result. The point of what I am doing is to produce an output like this (which my code currently does) for learning purposes:</p>
  
  <pre><code> ------- ------- ------- 
  |       | 2   7 |       |
  |   1 5 |       | 7 8   |
  |   6   | 4   1 |   3   |
   ------- ------- ------- 
  |     4 |       | 9     |
  | 1 9   |   3   |   2 5 |
  |       |       |       |
   ------- ------- ------- 
  |   8   |   9   |   1   |
  |     2 | 6   8 | 3     |
  | 6     |       |     4 |
   ------- ------- ------- 
  </code></pre>
  
  <p>I am using an <code>unsigned int[]</code> to represent the board and have a <code>static char[]</code> within the <code>printBoard</code> function for the purpose of displaying the board when I call <code>printBoard(const unsigned int* ac_board)</code>. What I was hoping for was having the <code>static char[]</code> be initialized with the formatting needed and have 81 copies from the <code>unsigned int[]</code> into the <code>static char[]</code> each time I call <code>printBoard</code></p>
  
  <p>At the moment I have not been able to achieve this, I have 81 * 2 copies occurring in my code following the pattern (I am compiling as <code>g++ -std=c++14 -O3 "$1" -o "$2"</code>):</p>
  
  <pre><code>...
     100000adc:   88 05 ba 05 00 00       mov    %al,0x5ba(%rip)        # 10000109c &lt;__ZZ10printBoardPKjE10s_printBuf+0x1c&gt;
     100000ae2:   8b 47 04                mov    0x4(%rdi),%eax
     100000ae5:   88 05 b3 05 00 00       mov    %al,0x5b3(%rip)        # 10000109e &lt;__ZZ10printBoardPKjE10s_printBuf+0x1e&gt;
     100000aeb:   8b 47 08                mov    0x8(%rdi),%eax
     100000aee:   88 05 ac 05 00 00       mov    %al,0x5ac(%rip)        # 1000010a0 &lt;__ZZ10printBoardPKjE10s_printBuf+0x20&gt;
     100000af4:   8b 47 0c                mov    0xc(%rdi),%eax
     100000af7:   88 05 a7 05 00 00       mov    %al,0x5a7(%rip)        # 1000010a4 &lt;__ZZ10printBoardPKjE10s_printBuf+0x24&gt;
     100000afd:   8b 47 10                mov    0x10(%rdi),%eax
     100000b00:   88 05 a0 05 00 00       mov    %al,0x5a0(%rip)        # 1000010a6 &lt;__ZZ10printBoardPKjE10s_printBuf+0x26&gt;
     100000b06:   8b 47 14                mov    0x14(%rdi),%eax
  ...
  </code></pre>
  
  <p>Is there a way to actually achieve 81 <strong>mov</strong> instructions rather than 81 * 2?</p>
  
  <p><strong>Below is my main.cpp</strong>:</p>
  
  <pre><code>#include &lt;ctime&gt;
  
  #include "print.hpp"
  
  
  // -----------------------------------------------------------------------------
  unsigned int g_board[81] = {
      0x20, 0x20, 0x20, 0x32, 0x20, 0x37, 0x20, 0x20, 0x20,
      0x20, 0x31, 0x35, 0x20, 0x20, 0x20, 0x37, 0x38, 0x20,
      0x20, 0x36, 0x20, 0x34, 0x20, 0x31, 0x20, 0x33, 0x20,
      0x20, 0x20, 0x34, 0x20, 0x20, 0x20, 0x39, 0x20, 0x20,
      0x31, 0x39, 0x20, 0x20, 0x33, 0x20, 0x20, 0x32, 0x35,
      0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
      0x20, 0x38, 0x20, 0x20, 0x39, 0x20, 0x20, 0x31, 0x20,
      0x20, 0x20, 0x32, 0x36, 0x20, 0x38, 0x33, 0x20, 0x20,
      0x36, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x34
  };
  
  // -----------------------------------------------------------------------------
  int main() {
      ::std::clock_t begin = clock();
      printBoard(g_board);
      ::std::clock_t end = clock();
      ::std::cout &lt;&lt; (end - begin) &lt;&lt; ::std::endl;
  
      return 0;
  }
  </code></pre>
  
  <p><strong>Here is my current best implementation of print.hpp</strong>:</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  
  // -----------------------------------------------------------------------------
  void printBoard(const unsigned int* ac_board) {
      static char s_printBuf[] = {
          ' ', '-', '-', '-', '-', '-', '-', '-', ' ', '-', '-', '-', '-',
          '-', '-', '-', ' ', '-', '-', '-', '-', '-', '-', '-', ' ', '\n',
          '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x',
          ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', '\n',
          '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x',
          ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', '\n',
          '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x',
          ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', '\n',
          ' ', '-', '-', '-', '-', '-', '-', '-', ' ', '-', '-', '-', '-',
          '-', '-', '-', ' ', '-', '-', '-', '-', '-', '-', '-', ' ', '\n',
          '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x',
          ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', '\n',
          '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x',
          ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', '\n',
          '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x',
          ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', '\n',
          ' ', '-', '-', '-', '-', '-', '-', '-', ' ', '-', '-', '-', '-',
          '-', '-', '-', ' ', '-', '-', '-', '-', '-', '-', '-', ' ', '\n',
          '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x',
          ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', '\n',
          '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x',
          ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', '\n',
          '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x',
          ' ', 'x', ' ', '|', ' ', 'x', ' ', 'x', ' ', 'x', ' ', '|', '\n',
          ' ', '-', '-', '-', '-', '-', '-', '-', ' ', '-', '-', '-', '-',
          '-', '-', '-', ' ', '-', '-', '-', '-', '-', '-', '-', ' ', '\n',
          0
      };
  
      s_printBuf[28]  = ac_board[0];
      s_printBuf[30]  = ac_board[1];
      s_printBuf[32]  = ac_board[2];
      s_printBuf[36]  = ac_board[3];
      s_printBuf[38]  = ac_board[4];
      s_printBuf[40]  = ac_board[5];
      s_printBuf[44]  = ac_board[6];
      s_printBuf[46]  = ac_board[7];
      s_printBuf[48]  = ac_board[8];
  
      s_printBuf[54]  = ac_board[9];
      s_printBuf[56]  = ac_board[10];
      s_printBuf[58]  = ac_board[11];
      s_printBuf[62]  = ac_board[12];
      s_printBuf[64]  = ac_board[13];
      s_printBuf[66]  = ac_board[14];
      s_printBuf[70]  = ac_board[15];
      s_printBuf[72]  = ac_board[16];
      s_printBuf[74]  = ac_board[17];
  
      s_printBuf[80]  = ac_board[18];
      s_printBuf[82]  = ac_board[19];
      s_printBuf[84]  = ac_board[20];
      s_printBuf[88]  = ac_board[21];
      s_printBuf[90]  = ac_board[22];
      s_printBuf[92]  = ac_board[23];
      s_printBuf[96]  = ac_board[24];
      s_printBuf[98]  = ac_board[25];
      s_printBuf[100] = ac_board[26];
  
      s_printBuf[132] = ac_board[27];
      s_printBuf[134] = ac_board[28];
      s_printBuf[136] = ac_board[29];
      s_printBuf[140] = ac_board[30];
      s_printBuf[142] = ac_board[31];
      s_printBuf[144] = ac_board[32];
      s_printBuf[148] = ac_board[33];
      s_printBuf[150] = ac_board[34];
      s_printBuf[152] = ac_board[35];
  
      s_printBuf[158] = ac_board[36];
      s_printBuf[160] = ac_board[37];
      s_printBuf[162] = ac_board[38];
      s_printBuf[166] = ac_board[39];
      s_printBuf[168] = ac_board[40];
      s_printBuf[170] = ac_board[41];
      s_printBuf[174] = ac_board[42];
      s_printBuf[176] = ac_board[43];
      s_printBuf[178] = ac_board[44];
  
      s_printBuf[184] = ac_board[45];
      s_printBuf[186] = ac_board[46];
      s_printBuf[188] = ac_board[47];
      s_printBuf[192] = ac_board[48];
      s_printBuf[194] = ac_board[49];
      s_printBuf[196] = ac_board[50];
      s_printBuf[200] = ac_board[51];
      s_printBuf[202] = ac_board[52];
      s_printBuf[204] = ac_board[53];
  
      s_printBuf[236] = ac_board[54];
      s_printBuf[238] = ac_board[55];
      s_printBuf[240] = ac_board[56];
      s_printBuf[244] = ac_board[57];
      s_printBuf[246] = ac_board[58];
      s_printBuf[248] = ac_board[59];
      s_printBuf[252] = ac_board[60];
      s_printBuf[254] = ac_board[61];
      s_printBuf[256] = ac_board[62];
  
      s_printBuf[262] = ac_board[63];
      s_printBuf[264] = ac_board[64];
      s_printBuf[266] = ac_board[65];
      s_printBuf[270] = ac_board[66];
      s_printBuf[272] = ac_board[67];
      s_printBuf[274] = ac_board[68];
      s_printBuf[278] = ac_board[69];
      s_printBuf[280] = ac_board[70];
      s_printBuf[282] = ac_board[71];
  
      s_printBuf[288] = ac_board[72];
      s_printBuf[290] = ac_board[73];
      s_printBuf[292] = ac_board[74];
      s_printBuf[296] = ac_board[75];
      s_printBuf[298] = ac_board[76];
      s_printBuf[300] = ac_board[77];
      s_printBuf[304] = ac_board[78];
      s_printBuf[306] = ac_board[79];
      s_printBuf[308] = ac_board[80];
  
      ::std::cout &lt;&lt; s_printBuf;
  }
  </code></pre>