في MIPS ، كيف يمكنني تقسيم المحتويات على اثنين؟

StackOverflow https://stackoverflow.com/questions/1569870

  •  21-09-2019
  •  | 
  •  

سؤال

لنفترض أن لدي $t0, ، وأرغب في تقسيم محتوياتها الصحيح على اثنين ، وتخزينها في $t1.

أمعائي يقول: srl $t1, $t0, 2

... لكن ألا تكون هذه مشكلة إذا ... قل ... كان البت الأيمن 1؟ أو هل يخرج كل شيء في الغسيل لأن البت الأكبر (إذا كان إيجابيًا) $t0 رقم فردي ، والذي يصبح حتى عند تقسيمه؟

علمني ، يا حكيمة ...

هل كانت مفيدة؟

المحلول

استخدام التعليمات 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 = 0xfffffffe

إذا تحولنا بت واحد إلى اليمين ، فإننا نحصل على 0x7ffffff

0x7ffffffff = 2147483647

بالطبع هذه ليست مشكلة عندما يكون الرقم عددًا صحيحًا إيجابيًا ، لأن بت الإشارة هي 0.

نصائح أخرى

للقيام بتقسيم عدد صحيح غير موقّع ، هذا صحيح. هذا يعمل فقط للأعداد الصحيحة غير الموقعة وإذا كنت لا تهتم بالجزء الكسري.

سترغب في استخدام مبلغ تحول قدره 1 ، وليس 2:

srl $t1, $t0, 1

إذا كنت تستخدم 2 ، فسوف ينتهي بك الأمر إلى القسمة على 4. بشكل عام ، والتحول x يقسم على 2x.

إذا كنت قلقًا بشأن "التقريب" وتريد التقريب ، فيمكنك فقط الزيادة بمقدار 1 قبل إجراء التحول المنطقي (غير الموقّع).

وذكر آخرون ذلك سابقًا ، لكنك تتحول فقط بمقدار 1 إلى تقسيمه على 2. تحول يمين ببتات n يقسم على 2^n.

لاستخدام التقريب (التقريب عند 0.5 أو أكثر) مع قيم التحول من N بخلاف 1 ، فقط أضف 1 << (N-1) قبل التحول.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top