【问题标题】:In MIPS, how do I divide register contents by two?在 MIPS 中,如何将寄存器内容除以二?
【发布时间】:2009-10-15 01:34:53
【问题描述】:

假设我有$t0,我想将其整数内容除以二,并将其存储在$t1中。

我的直觉告诉我:srl $t1, $t0, 2

...但是如果...说...最右边的位是1,那不是问题吗?还是因为最右边的位(如果是正数)使$t0 成为奇数,除以后变成偶数,所以这一切都洗白了?

教我啊,聪明的人...

【问题讨论】:

  • 奇数除以二不一定是偶数。
  • 那个班次实际上除以 4,而不是 2
  • sra 用于签名,srl 用于未签名...
  • @Tom:使用整数除法,7 / 2 = 3,这是奇数。

标签: mips divide


【解决方案1】:

使用指令sra:右移算术!!

sra $t1, $t0, 1

将 $t0 的内容除以 2 的第一次幂。

说明:移位寄存器值 正确的移位量(shamt)和 将值放在目的地 登记。符号位被移入。

操作:$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 = 0xffffffffe

如果我们向右移动一位,我们得到 0x7fffffff

0x7ffffffff = 2147483647

当数字为正整数时当然没问题,因为符号位为0。

【讨论】:

  • 我添加了一个示例,在 gxemul mips 上运行
【解决方案2】:

做无符号整数除法,没错。这仅适用于无符号整数并且如果您不关心小数部分。

【讨论】:

  • 你确实错过了一些东西。请参阅上面 Tom 的评论——您移动 1 以除以 2,而不是 2 位!
【解决方案3】:

您将希望使用 1 而不是 2 的移位量:

srl $t1, $t0, 1

如果你使用 2,你最终会除以 4。通常,右移 x 会除以 2x

【讨论】:

  • 哦,对了,我犯了一个愚蠢的错误。我的意思是 1 个,而不是 2 个,谢谢你抓住那个。
【解决方案4】:

如果您担心“四舍五入”并且想要四舍五入,则可以在执行逻辑(无符号)移位之前增加 1。

其他人之前已经说过了,但你只移动 1 来除以 2。右移 N 位除以 2^N。

若要使用 N 而非 1 的移位值的舍入(向上舍入 0.5 或更大),只需在移位前添加 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多