0

アセンブリの特定の行をNios IIのマシン コードに変換する際に問題があります。これらの行を正常にコンパイルしました:

START_TIMER = 0xF68C
r0 = 0x0
r8 = 0x8
label = 50000

#orhi r8, r0, %hiadj(label) --> 00000 01000 ???????????????? 110010
addi r8, r8, %lo(label) --> 01000 01000 1100001101010000 000100
subi r8, r8, 1 --> 01000 01000 1111111111111111 000100
bne r8, r0, START_TIMER --> 01000 00000 1111011010001100 011110

私が問題を抱えている問題の行は、この行の IMM16 です。

orhi r8, r0, %hiadj(label)

上記のハンドブックで説明されているように、「%lo」は「immed32 のビット [15..0] を抽出する」ことを意味し、「%hiadj」は「ビット [31..16] を抽出して immed32 のビット 15 を追加する」ことを意味します。ただし、2 進数の 50000 は 1100001101010000 であるため、16 ビットの数値です。私が見る限り、16 から 31 までのビットは含まれていません。0000000000000001 で試しましたが、正しくありません。

私は何を間違っていますか?

編集: 誤解を解消するためだけに。"orhi r8, r0, %hiadj(label)"を手動でコンパイルする方法を知りたいだけです。変数「r8」、「r0」、「label」は上記の通りであり、変化しない。

編集 2: 私が試したのは、50000 を 32 ビット バイナリに変換することです。

00000000000000001100001101010000

...ビット [31...16] を抽出:

0000000000000000

...ビット 15 を追加します (これは紛らわしいです。2^15 と 2^0 のどちらの価値があるかを教えてくれないので、両方を試してみましたが、まったく追加しませんでした)

0000000000000001
1000000000000000
0000000000000000

すべてが間違っています。

編集 3:このリンクに よると、16 ビット値が 0x8000 以上の場合、残りを 0xffff8000 に符号拡張し、ビット [31...16] に 1 を追加します。これにより、数値が 0x100008000 ~ 0x00008000 にオーバーロードされます。あなたの言ったこと、ジェラルド、どうやらまだ正しくないようです。

4

1 に答える 1

0

あなたが提供したコードは、16 ビットのハーフワードである「ラベル」の値を取得し、それを 32 ビットのワードに拡張してアドレスにします。ラベルは 16 ビット値であるため、ゼロをレジスタの上半分にシフトする必要があります。

したがって、上位ビットにゼロをロードしてから、下位ビットを追加します...

orhi  r8, r0, %hiadj(label) --> 00000 01000 0000000000000000 110010
addi  r8, r8, %lo(label) --> 01000 01000 1100001101010000 000100
于 2012-10-11T21:59:19.750 に答える