Moving data from inline assembly to array in C

I have a very simple problem; I have an array that needs to store me the results of some inline assembler. The question I have now is how can I move data from inline assembler to an array? I am using gcc to compile on an x86 machine. Consider the following simple code coding:

int main() {    
  int result[32];

  __asm__ __volatile__(  ".mov  esi, 32 \n\t"); 

  __asm__ __volatile__(  ".mov  edi, 32 \n\t");

  __asm__ __volatile__(  ".rept 32 \n\t");   
  __asm__ __volatile__(  ".mov  eax, esi \n\t");

  __asm__ __volatile__(  ".sub  eax, edi \n\t");

  __asm__ __volatile__(  ".sub  edi, 1 \n\t");

  //Code here for storing eax in result[0], result[1], ... result[31],

  __asm__ __volatile__(  ".endr \n\t");

  for(i=0; i<32; i++)
     printf("%d\n", results[i]); 

  return (0);
}

      

At the end, the output should look something like this:

result [0] = 32; result [1] = 31; result [2] = 30; ... result [31] = 1;

Any idea how this can be kept simple?

Thanks!

0


a source to share


3 answers


I would do it with this loop:

    __asm {
        lea edx, result
        mov ecx, 32
loop1:
        mov dword ptr [edx], ecx
        add edx, 4
        loop loop1
    }

      

Update (thanks to Bastien for the comment): after studying this document ( http://www.cs.virginia.edu/~clc5q/gcc-inline-asm.pdf ): variable accessible from asm (in GCC) should be static , source and destination objects are reversed, special syntax must be used to offset the array.



#include <stdio.h>

static int results[32];

int main(int argc, char** argv) 
{
    int i;

    asm volatile( "xor %eax, %eax \n\t");
    asm volatile( "movl $0x020, %edi \n\t");
    asm volatile( ".rept 32 \n\t");
    asm volatile( "mov %edi, _results(,%eax,4) \n\t");
    asm volatile( "dec %edi \n\t");
    asm volatile( "inc %eax \n\t");
    asm volatile( ".endr");

    for (i=0; i<32; i++) 
        printf("%d\n", results[i]);

    return 0; 
}

      

this worked on gcc 3.4.4 (cygwin)

+2


a source


This line, placed before the "sub edi" line, will do the copy (AT & T syntax - destination right):



__asm__ __volatile__(  "movl %ecx, $label(,%edi,$4) \n\t");

      

+1


a source


Please ignore my last comment, I'll try again:

int main() {

  int results[32];
  int i;

  __asm__ __volatile__(  "mov  %esi, 32 \n\t");   
  __asm__ __volatile__(  "mov  %edi, 32 \n\t");  
  __asm__ __volatile__(  ".rept 32 \n\t");   
  __asm__ __volatile__(  "mov  %eax, %esi \n\t");  
  __asm__ __volatile__(  "sub  %eax, %edi \n\t");  
  __asm__ __volatile__(  "sub  %edi, 1 \n\t");

   __asm__(".intel_syntax prefix");  
  __asm__ __volatile__( "mov dword ptr results[%edi*4], %eax \n\t");  
  __asm__(".att_syntax prefix");


  __asm__ __volatile__(  ".endr \n\t");

  for(i=0; i<32; i++)
     printf("%d\n", results[i]); 

  return 0;
}

      

When this occurs, an error message appears: undefined reference to `results'. I'm guessing it needs to be passed on to the inline assembly somehow?

+1


a source







All Articles