1

があり$t0、その整数の内容を 2 で割り、 に格納したいとし$t1ます。

私の腸は言う:srl $t1, $t0, 2

...しかし、もし...たとえば...一番右のビットが1だったら、それは問題ではないでしょうか? それとも、右端のビット (正の場合) が$t0奇数になり、分割すると偶数になるため、すべてウォッシュで出てきますか?

教えてくれよ、賢者よ…

4

4 に答える 4

8

使用命令 sra: 算術右シフト !!

sra $t1, $t0, 1

$t0 の内容を 2 の 1 乗で割ります。

説明: レジスタ値をシフト量 (シャムト) だけ右にシフトし、その値をデスティネーション レジスタに配置します。符号ビットがシフトインされます。

操作: $d = $t >> h;

Advance_pc (4);

構文: sra $d、$t、h

エンコーディング: 0000 00-- ---t tttt dddd dhhh hh00 0011

何でこれが大切ですか?整数 (プログラムの入力) を 2 で除算するこの単純なプログラムを確認してください。

    #include <stdio.h>

    /*
    * div divides by 2 using sra
    * udiv divides by 2 using srl
    */
    int div(int n);//implemented in mips assembly.
    int udiv(int n);
    int main(int argc,char** argv){

            if (argc==1) return 0;
            int a = atoi(argv[1]);

            printf("div:%d udiv:%d\n",div(a),udiv(a));
            return 1;
    }
    //file div.S
    #include <mips/regdef.h>

    //int div(int n)
    .globl div 
    .text
    .align 2
    .ent div
    div:
            sra v0,a0,1
            jr  ra        //Returns value in v0 register.
    .end div

    //int udiv(int n)
    .globl udiv
    .text
    .align 2
    .ent udiv
   udiv:
     srl v0,a0,1
     jr  ra        //Returns value in v0 register.
   .end udiv

コンパイル

root@:/tmp#gcc -c div.S
root@:/tmp#gcc -c main.c
root@:/tmp#gcc div.0 main.o -o test

テストドライブ:

root@:~# ./test 2
div:1 udiv:1
root@:~# ./test 4
div:2 udiv:2
root@:~# ./test 8
div:4 udiv:4
root@:~# ./test 16
div:8 udiv:8
root@:~# ./test -2
div:-1 udiv:2147483647
root@:~# ./test -4
div:-2 udiv:2147483646
root@:~# ./test -8
div:-4 udiv:2147483644
root@:~# ./test -16
div:-8 udiv:2147483640
root@:~#

どうなるか見てみ?srl命令が符号ビットをシフトしています

-2 = 0xfffffffe

1 ビット右にシフトすると、0x7fffffff が得られます。

0x7ffffffff = 2147483647

もちろん、符号ビットが 0 であるため、数値が正の整数の場合は問題ありません。

于 2009-10-15T01:47:10.577 に答える
4

2 ではなく 1 のシフト量を使用する必要があります。

srl $t1, $t0, 1

2 を使用すると、最終的に 4 で除算されます。一般に、右にxシフトすると 2 xで除算されます。

于 2009-10-15T01:47:08.043 に答える
4

符号なし整数除算を行うには、そうです。これは、符号なし整数に対してのみ機能し、小数部分を気にしない場合にのみ機能します。

于 2009-10-15T01:37:25.543 に答える
0

「丸め」が心配で、切り上げたい場合は、論理 (符号なし) シフトを行う前に 1 だけインクリメントできます。

そして他の人は以前にそれを述べましたが、2 で割るために 1 だけシフトします。N ビットの右シフトは 2^N で割ります。

1 以外の N のシフト値で丸め (0.5 以上での切り上げ) を使用するには、シフトの前に 1<<(N-1) を追加するだけです。

于 2009-10-15T02:19:28.937 に答える