2009-05-26 11 views
0

私は非常に単純な問題があります。私はいくつかの結果を格納する配列を持っている インラインアセンブラルーチン。私が持っている質問は、どのようにして のインラインアセンブラから配列にデータを移動することができるのですか?私はx86マシン上でコンパイルするためにgccを使用しています。終わりにインラインアセンブリから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); 
} 

、出力はそのようになります。次の簡単なコードfragementを考えてみましょう

結果を[0] = 32; 結果[1] = 31;結果[2] = 30; ... 結果[31] = 1;

誰でもいいのですが、どうすれば簡単にできますか?

ありがとうございます! "サブEDI" 行の前に置く。このラインは、(& T構文AT - 目的地は右側にある)のコピーを行います

+0

はじめに、アセンブラを別々のステートメントに分けないでください。コンパイラは、理論的には、それらの間の間隔でレジスタを踏み外すことができます。 – bdonlan

答えて

1

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

Intel構文を設定するべきではありませんか?私は、それが.intel_syntax no_prefixのようなもので、asmコードの最後に.att_syntaxプレフィックスがあると信じています。 –

+0

ターゲットアドレス/レジスタが左側にあるのか右側にあるのかを意味しますか?もしそうなら - 私は元のコードと同じ構文を使用する - あなたは確かに定数にレジスタをmovできなかった。 – sharptooth

+0

あなたが示唆したように、私は、しかし、私はエラーをメイン の#include INT(){ 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 __( "。intel_syntax接頭辞 "); __asm__ __volatile __( "MOVのDWORD PTR結果[%のEDI * 4]、%EAX \ n個の\ T"); __asmの__("。att_syntax接頭辞 "); __asm__ __volatile __(" .ENDRする\ n \ t "); } –

2

私はこのループであることをするでしょう:

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

更新(コメントため感謝バスティアン):このドキュメント(http://www.cs.virginia.edu/~clc5q/gcc-inline-asm.pdf)を勉強した後:(GCC)でのasmからアクセス 変数h静的であるために、ソース&宛先は逆になりますが、配列をオフセットするには特殊な構文を使用する必要があります。

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

これが私の最後のコメントを無視してくださいGCC 3.4.4(cygwinの)

+0

これはGCCでは動作しません。 –

+0

GCCについてはわかりませんが、x86アセンブリであり、GCC-ASM構文でも簡単に書けると思います。 – Andrey

+0

AT&Tの構文とても独特です::) – Andrey

1

に取り組んで、私はここで再びそれを試してみてください。

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

そうすることで、私は、エラーメッセージが表示されます: `results 'への未定義参照。 これはインラインアセンブリに何とかして渡す必要があると思いますか?

+0

あなたは$記号を使用しています。私の答えを更新しました: http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html – sharptooth

関連する問題