title: Why is gcc not writing to memory correctly when I use __asm__
body: <p>I have a piece of code that calls a BIOS text output function, <code>INT 0x10, AH=0x13</code>:</p>
  
  <pre><code>static void __stdcall print_raw(uint8_t row, uint8_t col, uint8_t attr,
                                 uint16_t length, char const *text)
  {
      __asm__ __volatile__ (
          "xchgw %%bp,%%si\n\t"
          "int $0x10\n\t"
          "xchgw %%bp,%%si\n\t"
          :
          : "d" (row | (col &lt;&lt; 8)), "c" (length), "b" (attr), "a" (0x13 &lt;&lt; 8), "S" (text)
      );
  }
  </code></pre>
  
  <p>I have another function which can print a number on the screen:</p>
  
  <pre><code>void print_int(uint32_t n)
  {
      char buf[12];
      char *p;
      p = buf + 12;
      do {
          *(--p) = '0' + (n % 10);
          n /= 10;
      } while (p &gt; buf &amp;&amp; n != 0);
  
      print_raw(1, 0, 0x0F, (buf + 12) - p, p);
  }
  </code></pre>
  
  <p>I spent significant time trying to figure out why nothing was coming up on the screen. I dug into it and looked at the code generated for <code>print_int</code>:</p>
  
  <pre><code>    .globl  print_int
      .type   print_int, @function
  print_int:
  .LFB7:
      .cfi_startproc
      pushl   %ebp
      .cfi_def_cfa_offset 8
      .cfi_offset 5, -8
      movl    $10, %ecx
      movl    %esp, %ebp
      .cfi_def_cfa_register 5
      pushl   %esi
      pushl   %ebx
      .cfi_offset 6, -12
      .cfi_offset 3, -16
      leal    -8(%ebp), %esi
      leal    -20(%ebp), %ebx
      subl    $16, %esp
      movl    8(%ebp), %eax
  .L4:
      xorl    %edx, %edx
      decl    %esi
      divl    %ecx
      testl   %eax, %eax
      je  .L6
      cmpl    %ebx, %esi
      ja  .L4
  .L6:
      leal    -8(%ebp), %ecx
      movl    $4864, %eax
      movb    $15, %bl
      movl    $1, %edx
      subl    %esi, %ecx
  #APP
  # 201 "bootsect.c" 1
      xchgw %bp,%si
      int $0x10
      xchgw %bp,%si
  
  # 0 "" 2
  #NO_APP
      addl    $16, %esp
      popl    %ebx
      .cfi_restore 3
      popl    %esi
      .cfi_restore 6
      popl    %ebp
      .cfi_restore 5
      .cfi_def_cfa 4, 4
      ret
  </code></pre>
  
  <p>If you look closely at the loop at <code>L4</code>, you'll see that it never stores anything into <code>buf</code>. It has omitted the instruction! it just divides it down and never stores any characters into the buffer.</p>