2009-05-26 2 views
0

J'ai un problème très simple; J'ai un tableau qui devrait me stocker les résultats d'une routine d'assembleur en ligne . La question que j'ai est maintenant comment puis-je déplacer les données de l'assembleur en ligne dans la matrice? J'utilise gcc pour compiler sur une machine x86. Considérons le code simple suivant fragement:Déplacement des données de l'assemblage en ligne dans la matrice en C

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

A la fin, la sortie devrait ressembler à quelque chose comme ça:

résultat

[0] = 32; résultat [1] = 31; résultat [2] = 30; ... résultat [31] = 1;

Quelqu'un d'une idée, comment cela pourrait être simple fait?

Merci!

+0

Pour commencer, ne séparez pas votre assembleur en déclarations séparées. Le compilateur peut en théorie écraser vos registres dans l'intervalle entre eux. – bdonlan

Répondre

1

Cette ligne mettre avant "sous edi" ligne fera la copie (AT & T syntaxe - destination est à droite):

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

Ne devriez-vous pas définir la syntaxe Intel avant? Je crois que c'est quelque chose comme .intel_syntax no_prefix, puis le préfixe .att_syntax à la fin du code asm. –

+0

Voulez-vous dire si l'adresse cible/registre est sur la gauche ou sur la droite? Si c'est le cas - j'utilise la même syntaxe que le code original - vous ne pourriez sûrement pas déplacer un registre dans une constante. – sharptooth

+0

Je l'ai essayé comme vous le suggérez, cependant, je reçois une erreur #include int main { résultats int() [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 ​​__ (".préfixe intel_syntax "); __asm__ __volatile __ ("Résultats mov dword ptr [% EDI * 4],% eax \ n \ t"); __asm ​​__ (." préfixe att_syntax "); __asm__ __volatile __ (" .endr \ n } –

2

Je le ferais avec cette boucle:

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

Mise à jour (merci Bastien pour commentaires): après avoir étudié ce document (http://www.cs.virginia.edu/~clc5q/gcc-inline-asm.pdf): variables accessible à partir asm (dans GCC) h pour être statiques, la source & destination est inversée, une syntaxe spéciale doit être utilisée pour décaler un tableau.

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

cela a fonctionné sur gcc 3.4.4 (Cygwin)

+0

Cela ne fonctionnera pas avec GCC –

+0

bien sûr, je ne connais pas GCC, mais c'est l'assemblage x86, et je suppose qu'il peut être facilement écrit avec la syntaxe GCC-ASM aussi – Andrey

+0

Syntaxe AT & T est si particulier ... :) – Andrey

1

S'il vous plaît ne pas tenir compte de mon dernier commentaire, j'essayer encore une fois ici:

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

Ce faisant, je reçois le message d'erreur : référence non définie à `results '. Je suppose que cela doit ensuite être passé en quelque sorte à l'assemblage en ligne?

+0

Vous utilisez le signe $ pour cela.Mise à jour ma réponse.Trouvé ici: http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html – sharptooth

Questions connexes