addr_dime : .word dime
はpoitlessly over-complexです。アドレスはすでにリンク時定数です。メモリ内にアドレスを格納すると(それ自身のアドレスを持つ別の場所で)、まったく助けにならないだけで間接指示の別のレイヤーが追加されます。 (実際には問題の原因です)
とにかく、
cmp
は、そのレジスタのオペランドを逆参照しないので、ポインタを比較しています。デバッガでシングルステップすると、レジスタ内の値がポインタであることがわかります。
R3にゼロ拡張、dime
で1バイトをロードするには、32ビットのロードを行うためにldr
を使用し
ldrb r3, dime
を行うことも\n
バイトになるだろう、と32ビットの比較が持っているでしょうeq
がtrueになるように一致させてください。
しかし、これは、PC相対アドレッシングモードに適合するには、dime
が十分に近い場合にのみ機能します。ほとんどのRISCマシンと同様、命令幅が固定であるため、ARMは任意の絶対アドレスを使用できません。
定数の場合、これを避ける最も簡単な方法は、ではなく、で、最初にメモリに格納します。その後、あなたはあなたのためのレジスタに定数を取得するためにアセンブラを依頼する
cmp r2, dime @ compare with immediate operand
またはldr r3, =dime
を使用することができ、数値定数を定義するために.equ dime, 'D'
を使用してください。あなたはアドレスでこれを行うことができますので、あなたは、これはあまりにも遠く離れPC相対アドレッシングモードのためにあるかもしれない静的データからロードを処理するための汎用的な方法である
ldr r2, =inputVal @ r2 = &inputVal
ldrb r2, [r2] @ load first byte of inputVal
行うことができます。
スタックアドレス(sub sp, #16
/mov r5, sp
など)を使用することで回避できます。その後、あなたは既に登録簿に住所を持っています。
これは、Cコンパイラが何をするかを正確です:上の
ARM32のgcc6.3から
char dime[4] = "D\n";
char input[4] = "xyz";
int foo(int start) {
if (dime[0] == input[0])
start += 10;
return start;
}
Godbolt compiler explorer:
foo:
ldr r3, .L4 @ load a pointer to the data section at dime/input
ldrb r2, [r3]
ldrb r3, [r3, #4]
cmp r2, r3
addeq r0, r0, #10
bx lr
.L4:
@ gcc greated this "literal pool" next to the code
@ holding a pointer it can use to access the data section,
@ wherever the linker ends up putting it.
.word .LANCHOR0
.section .data
.p2align 2
@@@ These are in a different section, near each other.
@@@ On Godbolt, click the .text button to see full assembler directives.
.LANCHOR0: @ actually defined with a .set directive, but same difference.
dime:
.ascii "D\012\000"
input:
.ascii "xyz\000"
ではなく、リテラル文字と比較するためにCを変更してみてくださいコンパイラが定数に最適化することができず、あなたが得るものを見ることができません。
internal_relocation(type:OFFSET_IMM)が修正されていないというエラーが表示されます。 – PCRevolt
@PCRevolt:ああ、ええ、アセンブラが魔法のようにデータに到達できるアドレッシングモードを使用するかどうか疑問に思いました。 ARMは固定長命令を使用し、任意の32ビット絶対アドレスのための余裕がありません。小さなオフセットを持つPC相対アドレッシングモードがあるため、ARMコードでは実際のコードの近くのブロックからデータを読み込むために "リテラルプール"を使用することがよくあります。 Cコンパイラの動作を参照してください:https://godbolt.org/g/xnRrNa。スタティックではなく、バッファ用にスタックメモリを使用した場合は、これを避けることができます。だからあなたはポインタと 'ldrb r3、[r5]'のアドレスを取得するだけです。 –
しかし、このシナリオではr5は何でしょうか? – PCRevolt