何らかの理由で、このコードをコンパイルしようとすると、コンパイラーはsyscall.s:72:invalid constant (0x172) after fixup
と言います。
.globl _mach_msg_trap$MACH
_mach_msg_trap$MACH:
stmfd sp!, {r4,r7}
mov r7, #370 /* this is line 72 */
svc 0
ldmfd sp!, {r4, r7}
bx lr
なぜそれをしているのか分かりません。小さい定数をr7
に入れると、うまく機能します。しかし、数値が大きいほど、このエラーが発生します。 mov r7, #300
とadd r7, #70
を実行して一時的に修正しました。これにより、目的の効果が得られます。エラーの原因はまだわかりません。
ARM命令は、movを使用して限られた範囲の即値のみをロードできます。問題は、値がmov命令自体にエンコードされる必要があることです。すべてのARM命令は32ビット幅であり、ARMv5までの元の命令セットは即値をエンコードするために合計で8 + 4ビットしかありませんでした。最初の8ビットは、任意の8ビット値intをロードできます。 0〜255の範囲で、4ビットは右に回転し、0〜30の間で2ずつステップします。
したがって、次のような値をロードできます。
#0
#122
#121 ror #24 = 30976
#230 ror #12 = 241172480
ただし、#370はこのスキームではロードできません。#185 ror #31
のようなものは必要ですが、これは不可能です。
現在の値をロードするには2つの方法があります。
ldr r7,=#370
次に、アセンブラは定数プールを作成し、pc相対アドレッシングを介してそこから値をロードします。通常、2つまでの命令で定数を作成することをお勧めします。それが不可能な場合(または値を再配置可能にする必要がある場合)は、ldrを使用します。
ARMv7以降では、movw
を使用してレジスタの下半分にある16ビット値をロードしながら上半分をゼロにし、movt
を使用して別の16ビット値をタッチせずに上半分にロードすることもできます。下半分。