1

$t2= と仮定0x55555550して、次の命令を実行します。

andi $t2, $t2, -1

$t2 は0x0005550

これは MIPS エミュレーター1で確認されています。

しかし、それは私が期待したものではありません。答えは 0x55555550 & 0xFFFFFFFF = 0x55555550 であるべきだと思います。and ロジックの前に、定数 -1 が 0xFFFFFFFF に符号拡張されたと思います。しかし、答えは 0x55555550 & 0x0000FFFF だったようです

-1 が 0xFFFFFFFF ではなく 0x0000FFFF に符号拡張される理由


脚注 1: 編集者注: 「拡張疑似命令」が有効になっている MARS は、これを複数の命令に展開し0xffffffffて tmp レジスタに生成するため、変更され$t2ません。そうしないと、MARS と SPIM の両方が、エンコードできないとしてエラーで拒否します。他のアセンブラは異なる場合があります。

4

3 に答える 3

6

あなたの予想は正しいが、実験結果の解釈は正しくない

$t2 は 0x0005550 になります。これは MIPS エミュレータで確認されています。

いいえ、これは正しくありません。したがって、次のいずれかです。

  1. どういうわけか、エミュレータが何をしているのかを誤解しています。エミュレータからの実際の値は、期待どおりです。
  2. または、想定どおりの前にありませんが0x55555550、代わりに (つまり) テストプログラムが正しくセットアップされていません。$t2 andi0x5550$t2

しかし、それは私が期待したものではありません。答えは 0x55555550 & 0xFFFFFFFF = 0x55555550 であるべきだと思います。and ロジックの前に、定数 -1 が 0xFFFFFFFF に符号拡張されたと思います。

はい、これ正しいです。そして、何が起こっているのか、そしてその理由を以下で説明します。

しかし、答えは 0x55555550 & 0x0000FFFF だったようです。-1 が 0xFFFFFFFF ではなく 0x0000FFFF に符号拡張される理由

そうではありませんでした。に符号拡張されまし0xFFFFFFFF。繰り返しますが、あなたは実験結果を間違って読んでいます [またはテスト プログラムにバグがあります]。


mipsシミュレーターとアセンブラーには疑似操作があります。

これらは、実際の物理的な命令として存在する場合と存在しない場合がある命令です。ただし、それらはアセンブラによって解釈され、一連の物理的/実際の命令が生成されます。

「純粋な」疑似操作の例はli(「すぐにロード」) です。対応する命令はありませんが、通常lui, ori(物理命令)の 2 つの命令シーケンスを生成します。

疑似操作を、、、、、などのアセンブラディレクティブと混同しないでください。.text.data.word.eqv

一部の疑似演算は、実際の物理命令と重複する可能性があります。それがあなたの例で起こっていることです。

実際、アセンブラは任意の命令を疑似操作の可能性として調べます。単一の物理的な命令でインテントを満たすことができると判断する場合があります。そうでない場合は、1 ~ 3 命令シーケンスを生成し、そのシーケンスの一部として[予約済み]$atレジスタ [これは] を使用できます。$1

mars、実際の実際の命令を確認するにBasicは、ソース ウィンドウの列を参照してください。

私の答えを完全にするために、以下のすべてはトップコメントで始まります。

3 つのサンプル プログラムを作成しました。

  1. addi元の投稿のように
  2. andi修正された投稿のように
  3. 符号なし引数andiを使用する

(1)を使用した元の質問のアセンブラソースは次のaddiとおりです。

    .text
    .globl  main
main:
    li      $t2,0x55555550
    addi    $t3,$t2,-1
    nop

mars解釈方法は次のとおりです。

 Address    Code        Basic                     Source

0x00400000  0x3c015555  lui $1,0x00005555         4     li      $t2,0x55555550
0x00400004  0x342a5550  ori $10,$1,0x00005550
0x00400008  0x214bffff  addi $11,$10,0xffffffff   5     addi    $t3,$t2,-1
0x0040000c  0x00000000  nop                       6     nop

addi16ビット即時に符号拡張するので、0xFFFFFFFF. 次に、2 の補数加算演算を実行すると、最終結果は次のようになります。0x5555554F

したがって、アセンブラは のために追加の命令を生成する必要がなかったaddiので、addi 疑似演算は単一の実数を生成しました。 addi


(2)andiソースは次のとおりです。

    .text
    .globl  main
main:
    li      $t2,0x55555550
    andi    $t3,$t2,-1
    nop

アセンブリは次のとおりです。

 Address    Code        Basic                     Source

0x00400000  0x3c015555  lui $1,0x00005555         4     li      $t2,0x55555550
0x00400004  0x342a5550  ori $10,$1,0x00005550
0x00400008  0x3c01ffff  lui $1,0xffffffff         5     andi    $t3,$t2,-1
0x0040000c  0x3421ffff  ori $1,$1,0x0000ffff
0x00400010  0x01415824  and $11,$10,$1
0x00400014  0x00000000  nop                       6     nop

うわあ!どうしたの?生成された 3 つのandi命令。

実際の 命令andiは、直接の引数を符号拡張しません。したがって、実数で使用できる符号なしandiの最大値は次のとおりです。0xFFFF

しかし、 を指定することで、符号拡張-1必要であることをアセンブラに伝えました(つまり)0xFFFFFFFF

したがって、アセンブラは単一の命令で目的を達成できず、上記のシーケンスが得られます。そして、生成されたシーケンスは使用できませんでしandiたが、登録フォームを使用する必要がありました: and. 以下は、andi生成されたコードをより使いやすい asm ソースに変換したものです。

    lui     $at,0xFFFF
    ori     $at,$at,0xFFFF
    and     $t3,$t2,$at

結果として、私たちはアンドを行っており0x555555500xFFFFFFFFこれは [まだ変更されていない] の値です0x55555550


(3) の無署名バージョンのソースは次のandiとおりです。

    .text
    .globl  main
main:
    li      $t2,0x55555550
    andi    $t3,$t2,0xFFFF
    nop

アセンブラの出力は次のとおりです。

 Address    Code        Basic                     Source

0x00400000  0x3c015555  lui $1,0x00005555         4     li      $t2,0x55555550
0x00400004  0x342a5550  ori $10,$1,0x00005550
0x00400008  0x314bffff  andi $11,$10,0x0000ffff   5     andi    $t3,$t2,0xFFFF
0x0040000c  0x00000000  nop                       6     nop

アセンブラは、16 進数の定数 (つまり、プレフィックス) を使用していることを認識すると、値を符号なし0x操作として実行しようとします。したがって、拡張に署名する必要はありません。そして、本物はその要求を満たすことができます。andi

この結果は0x5550

のマスク値を使用した場合0x1FFFF、それは符号なしになることに注意してください。ただし、これは 16 ビットより大きいため、アセンブラは要求を満たすために複数命令シーケンスを生成します。

そして、ここでの結果は0x15550

于 2016-10-18T21:15:21.440 に答える
0

仕様によると、即値は 16 ビット幅です。

したがって、andi $t2, $t2, -1と読むことができますandi $t2, $t2, 0xFFFF

すべての論理演算は即値をビット文字列として扱い、それを 32 ビットにゼロ拡張します。

于 2016-10-18T12:49:38.833 に答える