title: Calling Assembly functions in C, reverse a string
body: <p>I am trying to write a c program that will call an assembly function to reverse a string. However, I am having a hard time just getting the assembly code to iterate through the string to find the end character "0".</p>
  
  <p>My C code is as follows:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;ctype.h&gt;
  
  // These functions will be implemented in assembly:
  //
  void strrev(char *str) ;
  
  int main(){
      char *str1;
      str1 = strdup("Hello World");
      strrev(str1);
      printf("str1 reversed: \"%s\"\n", str1) ;
      free(str1);
      return 0;
  }
  </code></pre>
  
  <p>any my assembly code is simply:</p>
  
  <pre><code>; File: strrev.asm
  ; A subroutine called from C programs.
  ; Parameters: string A
  ; Result: String is reversed and returned.
  
  
      SECTION .text
      global strrev
  _strrev: nop
  strrev:
      push    ebp
      mov ebp, esp
  
      ; registers ebx,esi, and edi must be saved if used
      push ebx
      push edi
  
      xor esi, esi    
      xor eax, eax
      lea ecx, [esp+8]    ; load the start of the array into ecx
      jecxz   end     ; jump if [ecx] is zero
      mov edi, ecx
  
  reverseLoop:
      cmp byte[edi], 0
      je  end
      inc     edi 
      inc eax
      jmp reverseLoop
  
  end:
      pop edi     ; restore registers
      pop ebx
      mov esp, ebp    ; take down stack frame
      pop ebp
      ret
  </code></pre>
  
  <p>All I want this code to do right now is simply iterate through the string until it finds the end inside of reverseLoop. However, if I try to use gdb and step through the program, it seems to fail immediately after looking at the first character "H".</p>
  
  <p>Running with GDB with a break at line 25 while displaying the edi register with "display/c $edi" produces the following output:</p>
  
  <pre><code>(gdb) 
  reverseLoop () at strrev.asm:25
  25      cmp byte[edi], 0
  1: /c $edi = 72 'H'
  </code></pre>
  
  <p>Which is right, but if I step through down to inc edi, edi immediately becomes incorrect. It should be "E" since the second character in "Hello World" is "e". But, the gdb output lists it as "I":</p>
  
  <pre><code>27      inc     edi 
  1: /c $edi = 72 'H'
  (gdb) 
  28      inc eax
  1: /c $edi = 73 'I'
  </code></pre>
  
  <p>Am I doing something wrong when I am iterating through the edi register?</p>