Clemens
Clemens

Reputation:

Moving data from inline assembly into array in C

I have a very simple problem; I have an array which should store me the results of some inline assembler routine. The question that I have is now how can I move the data from the inline assembler into the array? I am using gcc for compiling on an x86 machine. Consider the following simple code fragement:

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 that:

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

Anyone an idea, how this could be simple done?

Thanks!

Upvotes: 0

Views: 4084

Answers (3)

Andrey
Andrey

Reputation: 4356

I would do that with this loop:

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

Update (thanks Bastien for comment): after studying this document (http://www.cs.virginia.edu/~clc5q/gcc-inline-asm.pdf): variable accessed from asm (in GCC) has to be static, source & destination are reversed, special syntax has to be used to offset an 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)

Upvotes: 2

Clemens
Clemens

Reputation:

Please ignore my last comment, I try it once again here:

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;
}

In doing so, I get the error message: undefined reference to `results'. I guess this needs then to be passed somehow to the inline assembly?

Upvotes: 1

sharptooth
sharptooth

Reputation: 170499

This line put before "sub edi" line will do the copying (AT&T syntax - destination is on the right):

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

Upvotes: 1

Related Questions