ldr命令はARMでどのように機能しますか?

ldr r0, #0x28 

ldr命令とは何ですか?あるオフセットから文字列をロードしますか?実際に読み込まれている文字列/値を見つけるにはどうすればよいですか?

コメント

  • よろしいですか' s #0x28ではなく=#0x28

回答

LDRは、32ビット定数(LDRH(ハーフワード):16ビット、LDRB(バイト):8ビット)をメモリから指定されたターゲットレジスタ(この例ではr0)にロードします。

32ビット定数は32ビットopcode(またはThumb命令の場合は16ビット)でエンコードできないため、アセンブラは参照命令の近くのテキストセグメントに定数を格納し、(を使用して値を参照します。通常)PC相対アドレス指定、つまりr15からのオフセット。

したがって、ldrは実際には疑似命令です。次のコード

 .code 32 main: ldr r0, =0x12345678 bx lr 

はアセンブラによって

00000000 <main>: 0: e51f0000 ldr r0, [pc, #-0] ; 8 <main+0x8> 4: e12fff1e bx lr 8: 12345678 .word 0x12345678 

に変換されます。元のldr命令で参照されている定数は、実際には命令自体ではなくアドレス0x8に格納されています。次に、アドレス0のldr命令は、PC相対アドレス指定を使用してこの値を参照します。実際のPC値は常に現在の命令のアドレス+8であるため、PCへのオフセットは(8ではなく)0です。これは互換性のために保持する必要がある初期のARMプロセッサパイプラインの影響です。

回答

これは、次のように簡単に変換できます。

r0 = 0x28; 

ARMアセンブリでは、#が即値をマークし、r0r1、…はレジスタです。 ldr命令は、次の構文形式をとることができます(最初の行はあなたのものです)。

LDR{type}{cond} Rt, [Rn {, #offset}] ; immediate offset LDR{type}{cond} Rt, [Rn, #offset]! ; pre-indexed LDR{type}{cond} Rt, [Rn], #offset ; post-indexed LDRD{cond} Rt, Rt2, [Rn {, #offset}] ; immediate offset, doubleword LDRD{cond} Rt, Rt2, [Rn, #offset]! ; pre-indexed, doubleword LDRD{cond} Rt, Rt2, [Rn], #offset ; post-indexed, doubleword 

回答

ldrなし=はPCの相対負荷を行います

これはラベルと番号の両方に当てはまります。

ただし、もちろんほとんど使用しませんアセンブリに直接番号を付けます。ラベルなしで逆アセンブリを提供した可能性がありますか?

GNU GASARMv8では次の両方が機能します。ラベル付き:

 ldr x0, pc_relative_ldr b 1f pc_relative_ldr: .quad 0x123456789ABCDEF0 1: /* x0 == 0x123456789ABCDEF0 */ 

オフセットあり:

 ldr x0, 0x8 b 1f .quad 0x123456789ABCDEF0 1: /* x0 == 0x123456789ABCDEF0 */ 

どちらも同等です。アセンブラはたまたまラベルを正しいオフセットに変換します。

アサーション付きのGitHubアップストリーム

STRにはARMv8のLDRのようなPC相対アドレス指定がないため、最初にアドレスをレジスタに計算する必要があります: https://stackoverflow.com/questions/28638981/howto-write-pc-relative-adressing-on-arm-asm/54480999#54480999

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です