title: Passing a pointer to an assembly function
body: <p>I'm rather new to assembly programming.  I'm using the x86 platform with GCC (Linux).</p>
  
  <p>I have a function that I want to call from C as:</p>
  
  <pre><code>myfunc ( unsigned char * s1, unsigned char * s2, int someint );
  </code></pre>
  
  <p>The function will take the s1 and s2 memory locations and compare them, then increment and compare, etc., doing some processing as it goes.  This is sort of like memcmp but I'm doing more.</p>
  
  <p>My question: if I pass a pointer into an assembly function?
  And then how do I say "give me the value stored at this memory address"?</p>
  
  <p>Here's what I have so far:</p>
  
  <p>To get the first function arg ("s1") off the stack, I do this (someaddress is a 32-bit integer, and I'm working on a 32-bit processor):</p>
  
  <pre><code>movl  8(%esp), %ecx
  movl  %ecx, someaddress
  </code></pre>
  
  <p>If I put <code>somevar</code> into <code>%eax</code> (or <code>%ebx</code>, etc.) and then printf it with <code>%p</code>, I see that its address and the address of the unsigned char pointer "<code>s1</code>" I passed it are the same.  But I suspect that what I've actually done is taken the memory address, converted it to an integer, and then put that integer in someaddress.</p>
  
  <p>For example, if I then do this:</p>
  
  <pre><code>movl  pos1, %eax
  movl  pos2, %ebx
  cmp   (%eax),(%ebx)
  </code></pre>
  
  <p>I get "Error: too many memory references for `cmp'".  I'm not entirely certain what that means, except "you screwed up" ;-)</p>
  
  <p>So...</p>
  
  <ul>
  <li>how to pass a pointer in and keep it as a pointer?</li>
  <li>how to use the value of said pointer in assembly?  (e.g., like <code>*ptr</code> in C)</li>
  </ul>
  
  <p>Do I want to look at the LEA operand?</p>
  
  <p>I'm using Richard Blum's "Professional Assembly Programming" as my guide, but Blum doesn't seem to cover this case.</p>
  
  <p><strong>Update</strong></p>
  
  <p>Thank you very much for your learned response!  </p>
  
  <p>Unfortunately, I'm still not able to dereference.  </p>
  
  <p>Here is a simplified example.  The assembly function takes a pointer and should echo it back.  Instead I get:</p>
  
  <pre><code>first_ptr points to 81 (should be 81) &lt;-- from C program
  the value is -1543299247 &lt;-- printf called from within assembler
  the value is -6028513 &lt;-- printf called from within assembler
  my function returned -6028513 &lt;-- return value printed from C program
  </code></pre>
  
  <p>C Program:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  
  int main (void) {
          unsigned char first;
          unsigned char * first_ptr;
  
          first = 'Q';
          first_ptr = &amp;first;
  
          printf ("first_ptr points to %i (should be 81)\n",*first_ptr);
  
          printf ("my function returned %i\n", myfunc(first_ptr));
          return 0;
  }
  </code></pre>
  
  <p>Assembly program:</p>
  
  <pre><code>.section .data
  
  msg:
    .asciz "the value is %i\n"
  
  .section .bss
  .lcomm str, 8
  
  .section .text
  .type myfunc, @function
  .globl myfunc
  myfunc:
  
    # save stack
    pushl %ebp
    movl  %esp, %ebp
  
    # save string arg from stack to "str"
    movl  8(%esp), %ecx
    movl  %ecx, str
  
    # let's try printing the ecx dereference
  
    pushl (%ecx)
    pushl $msg
    call printf
  
    # put the value of str on the stack 
    # and call printf
  
    pushl (str)
    pushl $msg
    call printf
  
    # now return the character at pos1
    movl  (str), %eax
  
    # restore the stack
    movl  %ebp, %esp
    popl  %ebp
  
    ret
  </code></pre>