让我们说我有$t0,我想除以2的整数内容,并将其存储在$t1

我的直觉说:srl $t1, $t0, 2

...但是那不是......如果说一个问题... ...最右位为1?或所有这一切在洗涤出来,因为最右边的位(如果阳性)品牌$t0奇数,这变得甚至当分割

教我,哦,聪明的人......

有帮助吗?

解决方案

使用指令SRA:右移运算!!

sra $t1, $t0, 1

除法$ T0由2中的第一功率的内容。

  

描述:改变的寄存器值   向右的移位量(shamt)和   宿价值目标   寄存器。符号位被移位英寸

     

操作:$ d = $ T >>小时;

     

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

如果我们一个位向右移,我们得到0x7FFFFFFF的

  

0x7ffffffff = 2147483647

当然,这不是一个问题,当数量是正整数,因为符号位为0。

其他提示

要进行无符号整数除法,这就是正确的。这仅适用于无符号整数,如果你不关心的小数部分。

您将要使用的1的偏移量,而不是2:

srl $t1, $t0, 1

如果您使用2,则最终将通过4.分割通常,由右移位的 X 除以2 X

如果您担心“四舍五入”,你想圆了,你可以通过做1的逻辑(无符号)移前刚刚递增。

和其他先前所说它但只由2 ^ N由1转变为除以2,一种右移由N位分歧。

要使用舍入与其他大于1 N个位移值(在0.5或更大的舍入),只需添加1 <<(N-1)之前的偏移。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top