tags:

views:

1027

answers:

3

Hi

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!

+1  A: 

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");
sharptooth
Shouldn't you set Intel syntax before? I believe it's something like .intel_syntax no_prefix, then .att_syntax prefix at the end of the asm code.
Bastien Léonard
Do you mean whether the target address/register is on the left or on the right? If so - I use the same syntax as the original code - you surely couldn't mov a register into a constant.
sharptooth
I tried it as you suggested, however, I get an error#include <stdio.h>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");}
+2  A: 

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)

Andrey
This won't work with GCC.
Bastien Léonard
sure, I don't know GCC. but it is x86 assembly, and I suppose it can be easily written with GCC-ASM syntax too.
Andrey
Andrey
+1  A: 

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?

You use the $ sign for that. Updated my answer. Found that here:http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
sharptooth