Frage

Lassen Sie uns sagen, ich habe $t0, und ich möchte seine ganze Zahl Inhalte durch zwei teilen, und speichern Sie es in $t1.

Mein Bauch sagt: srl $t1, $t0, 2

... aber nicht, dass ein Problem, wenn ... sagen wir sein ... das am weitesten rechts stehende Bit war 1? Oder macht es alle in der Wäsche kommen, weil die am weitesten rechts stehende Bit (falls positiv) macht $t0 eine ungerade Zahl, die selbst wird, wenn geteilt?

Lehre mich, o Weisen ...

War es hilfreich?

Lösung

Gebrauchsanleitung sra: Umschalt rechts Arithmetik !!

sra $t1, $t0, 1

Dividiert den Inhalt von $ t0 durch die erste Potenz von 2.

  

Beschreibung: Verschiebt einen Registerwert   rechts um den Verschiebungsbetrag (shamt) und   legt den Wert in dem Ziel   registrieren. Das Vorzeichenbit wird verschoben in.

     

Operation: $ d = $ t >> h;

     

advance_pc (4);

     

Syntax: sra $ d, $ t, h

     

Encoding:   0000 00-- --- t tttt dddd dhhh hh00   0011

Warum ist das wichtig? Überprüfen Sie dieses einfache Programm, dass teilt eine ganze Zahl (Programm Eingang) von 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

Compile

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

Die Testfahrten:

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@:~#

sehen, was passiert? Die srl Befehl wird die Vorzeichen-Bit Verschiebung

  

-2 = 0xfffffffe

Wenn wir ein Bit nach rechts verschieben, erhalten wir 0x7fffffff

  

0x7ffffffff = 2147483647

Natürlich ist dies kein Problem, wenn die Zahl eine positive ganze Zahl, da das Vorzeichenbit 0 ist.

Andere Tipps

unsigned Integer-Division zu tun, das ist richtig. Dies funktioniert nur für ganze Zahlen ohne Vorzeichen, und wenn Sie über den Bruchteil egal.

Sie wollen einen Verschiebungsbetrag von 1 verwenden, nicht 2:

srl $t1, $t0, 1

Wenn Sie 2 verwenden, werden Sie von 4. In der Regel am Ende teilen, Verschieben nach rechts von x dividiert durch 2 x .

Wenn Sie sind besorgt über „Runden“ und Sie wollen aufrunden, können Sie einfach erhöhen, um 1, bevor die logische (unsigned) Verschiebung zu tun.

Und andere haben es bereits erwähnt, aber nur um 1 zu dividieren verschieben, indem 2. Eine Verschiebung nach rechts von N Bits dividiert durch 2 ^ N.

Rundung zu verwenden (Rundung bei 0,5 oder mehr nach oben) mit Verschiebungs-Werten von N ungleich 1 ist nur 1 hinzufügen << (N-1) vor der Verschiebung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top