ldr r0, #0x28
ldr
命令とは何ですか?あるオフセットから文字列をロードしますか?実際に読み込まれている文字列/値を見つけるにはどうすればよいですか?
コメント
回答
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アセンブリでは、#
が即値をマークし、r0
、r1
、…はレジスタです。 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 */
どちらも同等です。アセンブラはたまたまラベルを正しいオフセットに変換します。
STRにはARMv8のLDRのようなPC相対アドレス指定がないため、最初にアドレスをレジスタに計算する必要があります: https://stackoverflow.com/questions/28638981/howto-write-pc-relative-adressing-on-arm-asm/54480999#54480999
#0x28
ではなく=#0x28
?