0

私はアセンブリ言語が初めてで、奇妙なエラーが発生しています。プログラムは、ユーザーが入力した整数の最下位 4 ビットを表示することになっています。8 より大きい数値に対しては機能しますが、8 以下の数値に対しては、1 があるべき桁を出力します。8 の場合は 1000 ではなく 8000 を出力し、5 の場合は 0401 を出力します。理由がわかりません。誰か助けてもらえますか?

        .data
inPrompt:   .asciiz "Enter an integer: "
outLab:     .asciiz "Least significant 4 bits of int entered are "
############################ code segment ################################
        .text
        .globl main
main:
        li $v0, 4
        la $a0, inPrompt        
        syscall                   # print input prompt

        li $v0, 5
        syscall                   # read input integer

        move $t0, $v0

        li $v0, 4
        la $a0, outLab        
        syscall

        li $v0, 1

        andi $a0, $t0, 8               
                syscall

        andi $a0, $t0, 4             
                syscall

        andi $a0, $t0, 2             
                syscall

        andi $a0, $t0, 1        
                syscall
          ##########################################################

                li $v0, 10               # exit
                syscall
4

1 に答える 1

0

問題は、数値のビットではなく、(2 のべき乗の因数で)数値の加法分解を効果的に計算して出力していることです。

簡単に言えば、たとえば「ビット 4」の場合
  andi $a0, $t0, 4
、レジスタに格納されA0ます ...
- ..レジスタ4内の値に 4 の加算係数がある場合の値T0(たとえば、4、5、6、7、12、13 など) .)
および
- ... の値にT0加算係数 4 がない場合 (たとえば、0、1、2、3、8、9、10 など) は値 0。

これは、より正確には、 なぜあなた5が得る のかを説明しています04015 is 4 + 15 is 0 * 8 + 4 + 0 * 2 + 1

あなたがする必要があるのは、次の2つのいずれかです。

  • andi操作結果の結果がゼロでないかどうかをテストし、その場合、syscall を呼び出す前に $a0 に 1 をロードする
    か、
  • [ビット単位]andi演算結果を対応するビット数だけシフトします (「8 ビット」をテストする場合は 3 回、「4 ビット」をテストする場合は 2 回、「2 ビット」をテストする場合は 1 回)。

最初の提案は、「andi + syscall」グループの代わりに、次のような結果になります。

            andi $a0, $t0, 4
            blez $a0, outBit4  # bit is zero output integer value 0
            li $a0, 1          # bit is one  ouptut integer value 1 (repl 4 by 1)
  outBit4:  syscall

編集
プログラムを16 LoC未満に保つことについて... (ところで、この要件と他のヒントが示すhomeworkので、コードを提供するのではなく、一般的なアイデアを提供します)コード
を短縮する方法はいくつかありますが、16 LoCセットアップで9行が使用されていることを考えると、要件は少し難しいです。ユーザーに入力を求め、入力を取得して保存し、回答の開始を出力します...

最も一般的なアプローチは、1 つ (または複数のネストされた) ループを使用することです。この例では、単一のループで十分です。基本的にはほぼ同じことを 4 回繰り返す必要があるため、ループ自体を管理する (つまり、パラメーターをインクリメントし、ループ条件の終了を検出する) ためにいくつかの LoC を追加することを犠牲にして、次のように記述できます。パラメータ化された方法で単一の作業単位を処理し、このロジックをループ内に持つスニペット。

わずかに関連するアプローチは、サブルーチンを使用することです。これにより、繰り返されるロジックがサブルーチンに記述され、複数回呼び出すことができ、さまざまな引数を渡してパラメーター化された動作を実現します。

上記について言及したのは、それらがアセンブリ言語で、そして実際に大規模なプログラミングで非常に一般的に使用されているためです。しかし、現在の「andi ベース」のロジックでは、これらのアプローチのどちらも LoC が 16 を下回ることはないと思います。ループ構造とビット シフト ロジックを使用する必要がある場合があります。

于 2013-03-04T05:14:01.760 に答える