2017-10-26 13 views
1

私はGNUアセンブリで配列を扱おうとしています。私の意見では、次のコードでは、値3で終了しなければなりません。しかし、それは私の意見movw inArr(%rip, %rcx, 2), %diコマンドでは13AT&T GASアセンブリの配列アドレス指定。 RIPからのレジスタのオフセットが機能しません

.section __DATA,__data 
    inArr: 
    .word 13, 2, 3, 4, 5, 6, 7, 8, 9, 10 

    outArr: 
    .fill 10, 2 
.section __TEXT,__text 
.globl _main 
_main: 


    movq $3, %rcx 

    movw inArr(%rip, %rcx, 2), %di # load *((rcx * 2)+ rip + &inArray) into %di, isn't it? 
    movl $0x2000001, %eax   # exit 
    syscall 

で終了%di = inArr[%rcx]のようなものと同じです。残念ながら、私はGASでarrayを使った例は見つけられません。

このコードで何が問題になっていますか?そして配列のn番目の要素をどのように扱いますか?

+0

あなたは位置独立コードを必要としない場合は、 'movzwlのinArr(、%のRCX、2)、%のedi'を使用することができます。しかし、あなたはおそらく* OS XのPICが必要です* –

+0

ありがとう! これは、「エラー:32ビット絶対アドレス指定は64ビットモードではサポートされていません」というエラーを表示します。 OS X用のPICが見つかりません。これを明確にすることはできますか? –

+1

PIC =位置に依存しないコード。 OS Xの絶対アドレス指定は、OS Xのx86-64コードではまったく使用できません。 ([Linuxとは異なります](https://stackoverflow.com/questions/43367427/32-bit-absolute-addresses-no-longer-allow-in-x86-64-linux)) –

答えて

2

インデックス付きRIP相対アドレッシングモードはありません。アセンブラでエラーが発生するはずです。代わりにこれを使用します。

lea inArr(%rip), %rdi 
    movzwl (%rdi, %rcx, 2), %edi 
+2

'%rdi'ポインタがtmpレジスタを必要としないようにします。 (OPが本当にその単語をRDIの下位16ビットにマージしたいのでない限り)。 –

+0

@Peter、はい、私はraxを使用しました。元のコードが次の行にリロードしたからです。しかし、exitシステムコールは、rdiの下位8ビットしか使用しないため、同等の安全性があり、コンテキストなしで最良の選択となる可能性が高くなります。 – prl

+0

ありがとう!できます。しかし、それはまだ私にとって非常に変だ。私の意見では、あなたのコードは同じ方法で動作しています。私はOS XでGASを使用していますが、インデックス作成を無視してもエラーは出ません。 GASの配列に関するリンクを私に教えてもらえますか? –

関連する問題