title: Custom Freestanding printf only displaying one letter and random capital S
body: <p>I am trying to develop my own kernel which I am booting to with GRUB.</p>
  
  <p>In order to display strings with variables, I have started to develop my own <code>printf(char*, ...)</code> function.</p>
  
  <p>Here is the kernel.cpp (thanks to <a href="https://www.youtube.com/watch?v=1rnA6wpF0o4&amp;list=PLHh55M_Kq4OApWScZyPl5HhgsTJS9MZ6M&amp;index=1" rel="nofollow noreferrer">Write Your Own Operating System YouTube tutorial for the main loading part</a> (printf is my code entirely))</p>
  
  <pre><code>#include &lt;stdarg.h&gt;
  
  
  #define VGA_BLACK 0
  #define VGA_BLUE 1
  #define VGA_GREEN 2
  #define VGA_CYAN 3
  #define VGA_RED 4
  #define VGA_MAGENTA 5
  #define VGA_BROWN 6
  #define VGA_GREY 7
  #define VGA_BRIGHT 8
  
  #define VGA_DEFAULT_FG VGA_GREEN
  #define VGA_DEFAULT_BG VGA_BLACK
  
  volatile char* videoMemory = (volatile char*)0xB8000;
  unsigned int color = ((VGA_DEFAULT_BG&lt;&lt;4) | (VGA_DEFAULT_FG &amp; 0x0F));
  
  void putchar(char c){
    *videoMemory++ = c;
    *videoMemory++ = color;
  }
  
  void printInt(int number){
    if(number &lt;= 0){
      putchar('0');
      return;
    }
    int diget = number/10;
    char c = diget + 48;
    putchar(c);
    int newNum = diget%10;
    printInt(newNum);
  }
  
  int strlen(char* str){
    int len = 0;
    for(int i = 0; str[i] != '\0'; i++){
      len++;
    }
    return len;
  }
  
  void printf(char* msg, ...){
    va_list args;
    va_start(args, msg);
    for(int i = 0; i &lt; strlen(msg); i++){
      if(msg[i] == '%'){
        i++;
        if(msg[i] == 'd'){
          i++;
          int res = va_arg(args, int);
          printInt(res);
        } else if(msg[i] == 's'){
          i++;
          char* c;
          do{
            c = va_arg(args, char*);
  
            putchar(*c);
          } while(c != '\n');
        } else {
          putchar('%');
        }
      } else {
        putchar(msg[i]);
      }
    }
    va_end(args);
  }
  
  
  void setColor(char fg, char bg){
    color = ((bg&lt;&lt;4) | (fg &amp; 0x0F));
  }
  
  
  typedef void (*constructor)();
  extern "C" constructor start_ctors;
  extern "C" constructor end_ctors;
  extern "C" void callConstructors(){
    for(constructor* i = &amp;start_ctors; i != &amp;end_ctors; i++){
      (*i)();
    }
  }
  
  extern "C" void kernelMain(void* multibootStructure, unsigned int magicNumber){
    setColor(VGA_GREEN+VGA_BRIGHT, VGA_BLACK);
    printf("Booting %s", "Test System");
    while(true);
  }
  </code></pre>
  
  <p>Result:
  <a href="https://i.stack.imgur.com/vKHal.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/vKHal.png" alt="enter image description here"></a></p>
  
  <p>As you can see, it displays the first character and 'S'.</p>
  
  <p>If I were to change the message to "My Custom Kernel", this is the result:</p>
  
  <p><a href="https://i.stack.imgur.com/1li7s.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/1li7s.png" alt="enter image description here"></a></p>
  
  <p>As you can see here, it again prints the first letter and then 'S'.</p>
  
  <p>Why is this happening? By my understanding, va_args changes <code>char</code> to <code>int</code>, however this does not explain why it only displays the first letter along with an 'S'.</p>
  
  <p>Why is this happening and how can I fix this?</p>
  
  <p>Edit:
  This has also been compiled with the flags: <code>-m32 -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore</code></p>