次のRISC-Vアセンブリコード(RV32)を使用して問題を表示します。JALオフセットを処理するためにRISCVリンカーが必要です
start: jal end
end: jal start
私は次の出力を与える、私はそれを分解し、生成されたコード...
riscv32-unknown-eft-objdump -D example.o
を確認するには
riscv32-unknown-elf-as -m32 example.s -o example.o
...次の簡単なコマンドを使用してアセンブラを起動します。 ..
00000000 <start>:
0: 004000ef jal 4 <end>
00000004 <end>
4: ffdff0ef jal 0 <start>
最初の 'jal'は、アドレス4の次の行にジャンプするために、PCに4を追加する必要があることを正しく示しています(注意:jal命令の即値の奇妙なレイアウトは、命令エンコード2は、CPUで2を掛けて実際のオフセット4を得る)。 2番目の 'jal'はオフセットとして-2を持ちます。ここでも、CPUを2倍した場合、オフセットとして-4を使用できます。
実際には、ELF情報を含まないraw出力ファイルを生成したいだけで、2つの命令を構成する8バイトだけで構成されています。私はマイクロコントローラに対して直接実行しており、そのマイクロコントローラはオペレーティングシステムを実行していません。出力を不揮発性RAMにフラッシュし、リセット時に実行するようにします。
だから私は...バイナリ出力を生成するには、以下のリンカコマンドを使用
riscv32-unknown-elf-ld --oformat=binary example.o -o example
しかし、これは生成された出力バイトを見て、次のコマンドを使用しているため、相対アドレス指定の値を失っているようです。.. 。
xxd example
は... ...次のような結果になります
00000000: ef00 0000 eff0 ffff
リトルエンディアンであることを考慮すると、4バイトの各セットは、以前に見た逆アセンブリとは逆の順序であることを意味します。最初のジャンプ '000000ef'がジャンプオフセットを失ったことがわかります。 2回目のジャンプ 'fffff0ef'は、2回の補数を適用する前後でも異なりますが、-1となるのは間違いです!
ジャンプオフセットがどのように壊れているか考えてください。オフセットを正しく処理するためにリンカに指定する必要があるいくつかのオプションがありますか?私は何も明白ではないし、LinuxとGNUの初心者としても悩まされている。