2012-03-16 8 views
1

インラインアセンブリコードに問題があります。私はローカルの静的配列からARMプラットフォーム上のレジスタに項目をロードしようとしています。残念ながら私はどのようにGCCに配列にポインタを渡して登録するべきかを知らない。このレジスタは、配列への間接アクセスのために使用されます。gccインラインアセンブラ(ARM)で配列を操作する

// should return argv[1] 
int test() { 
    int argv[4] = {4, 3, 2, 1}; 
    int out; 

    __asm__ volatile (
     "ldr r0, %[ARGV]" "\n\t" 
     "mov r1, #4" "\n\t" 
     "ldr r2, [r0, r1]" "\n\t" 
     "mov %[OUT], r2" 
     : [OUT] "=r" (out) 
     : [ARGV] "m" (argv) // <==== i don't know which constraint put here :/ 
     : "r0", "r1", "r2" 
    ); 

    return out; 
} 

GCCのスローエラーと私はそれを修正する方法は考えていません:

Assembler messages: 
Error: invalid offset, value too big (0xFFFFFFFC) 

Thxを

編集:私は、Android NDKでそれをコンパイルした(腕のlinux-androideabi-をG ++)

+0

これは、clangを使って私にとってうまく組み立て、リンクして動作します。何があなたのために起こっているのか分かりません。あなたはそれが間違っていることがこのコードにあると確信していますか? – mattjgalloway

+0

私はAndroid NDK(arm-linux-androideabi-g ++)でコンパイルすると言うことを忘れています – zdenek

+0

代わりに 'argv'の制約を' 'rm" 'に設定するとうまくいくのですか? – mattjgalloway

答えて

1

私はそれがこのように動作するはずだと思う:

[ARGV] "r" (argv) 

「レジスタのアドレスをレジスタにロードする」と書かれています。

+0

ええ、そうです。私は 'MOV'で' LDR'インストゥルメンツを置き換え、 'r'制約を使いました。どうも。 – zdenek

1

ARGVまたはOUTをレジスタ間で移動する必要はありません。つまり、レジスタの制約が処理します。

"mov r1, #4\n\t" 
"ldr %[OUT], [%[ARGV], r1]\n\t" 
: [OUT] "=r" (out) 
: [ARGV] "r" (argv) 
: "r1" 

注:このコードでは、最適化設定が高すぎるとコンパイルすると問題が発生します。 (私はそれを解決する方法はわかりません:-O0を使用してください)