MIPS array indexing using a displacement in lw for a known constant index?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







1















I am trying to translate from C this line of code of a nested array p=A[B[6]] that I've found on the book I'm studying MIPS from.
Because I am pretty sure that the solution from the book is wrong or, at least, much more complicated than what it needs to be.



The base address of the array A is stored in the register $s1, the base address of B is stored in $s2 and the value of g is stored in $s0.



My translation of p=A[B[6]] would be (please tell me if it is correct):



lw $t0, 24($s2) #load from memory B[6] in the register $t0
sll $t0, $t0, 2 #$t0=$t0*4
add $t0, $t0, $s1 #add to $t0 the address of A[B[6]]
lw $t0, 0($t0) #$t0=A[B[6]]


While instead the book (which is full of other errors) offers this solution:



addi $t0, $0, 6
sll sll $t0, $t0 2
add $t1, $s2, $t0
lw $t2, 0 ($t1)
sll $t2, $t2 2
add $t3, $s1, $t2
lw $s0, 0 ($t3)


Is my code correct or is the book right?










share|improve this question































    1















    I am trying to translate from C this line of code of a nested array p=A[B[6]] that I've found on the book I'm studying MIPS from.
    Because I am pretty sure that the solution from the book is wrong or, at least, much more complicated than what it needs to be.



    The base address of the array A is stored in the register $s1, the base address of B is stored in $s2 and the value of g is stored in $s0.



    My translation of p=A[B[6]] would be (please tell me if it is correct):



    lw $t0, 24($s2) #load from memory B[6] in the register $t0
    sll $t0, $t0, 2 #$t0=$t0*4
    add $t0, $t0, $s1 #add to $t0 the address of A[B[6]]
    lw $t0, 0($t0) #$t0=A[B[6]]


    While instead the book (which is full of other errors) offers this solution:



    addi $t0, $0, 6
    sll sll $t0, $t0 2
    add $t1, $s2, $t0
    lw $t2, 0 ($t1)
    sll $t2, $t2 2
    add $t3, $s1, $t2
    lw $s0, 0 ($t3)


    Is my code correct or is the book right?










    share|improve this question



























      1












      1








      1








      I am trying to translate from C this line of code of a nested array p=A[B[6]] that I've found on the book I'm studying MIPS from.
      Because I am pretty sure that the solution from the book is wrong or, at least, much more complicated than what it needs to be.



      The base address of the array A is stored in the register $s1, the base address of B is stored in $s2 and the value of g is stored in $s0.



      My translation of p=A[B[6]] would be (please tell me if it is correct):



      lw $t0, 24($s2) #load from memory B[6] in the register $t0
      sll $t0, $t0, 2 #$t0=$t0*4
      add $t0, $t0, $s1 #add to $t0 the address of A[B[6]]
      lw $t0, 0($t0) #$t0=A[B[6]]


      While instead the book (which is full of other errors) offers this solution:



      addi $t0, $0, 6
      sll sll $t0, $t0 2
      add $t1, $s2, $t0
      lw $t2, 0 ($t1)
      sll $t2, $t2 2
      add $t3, $s1, $t2
      lw $s0, 0 ($t3)


      Is my code correct or is the book right?










      share|improve this question
















      I am trying to translate from C this line of code of a nested array p=A[B[6]] that I've found on the book I'm studying MIPS from.
      Because I am pretty sure that the solution from the book is wrong or, at least, much more complicated than what it needs to be.



      The base address of the array A is stored in the register $s1, the base address of B is stored in $s2 and the value of g is stored in $s0.



      My translation of p=A[B[6]] would be (please tell me if it is correct):



      lw $t0, 24($s2) #load from memory B[6] in the register $t0
      sll $t0, $t0, 2 #$t0=$t0*4
      add $t0, $t0, $s1 #add to $t0 the address of A[B[6]]
      lw $t0, 0($t0) #$t0=A[B[6]]


      While instead the book (which is full of other errors) offers this solution:



      addi $t0, $0, 6
      sll sll $t0, $t0 2
      add $t1, $s2, $t0
      lw $t2, 0 ($t1)
      sll $t2, $t2 2
      add $t3, $s1, $t2
      lw $s0, 0 ($t3)


      Is my code correct or is the book right?







      assembly mips micro-optimization






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 5 at 20:27









      anothermh

      3,36931733




      3,36931733










      asked Jan 3 at 20:30









      AnnaAnna

      111




      111
























          1 Answer
          1






          active

          oldest

          votes


















          1














          Both versions are logically correct; the only problem with the book version is that it's very inefficient.



          It fails to optimize based on the fact that 6 is an assemble-time constant, so the 6*4 can be an immediate displacement in the lw, instead of calculated at runtime in a register and added to the base separately.



          lw has room for 16 bits of immediate offset; it's silly not to take advantage and restrict yourself to only ever using 0. It's an I-type instruction for a reason, dedicating lots of coding space to allowing a large offset.



          Other than that your versions are equivalent. The book version calculates 6<<2 in a register and adds it to the base of B ($s2). It gets the initial 6 into a register by adding to the zero-register.



          Both yours and the book's use add instead of addu. Not sure why you want to trap on signed overflow, especially when doing address math. C compilers normally always use addu. (Signed overflow is undefined behaviour in C, but compiler developers know that it's usually more useful / expected for it to silently wrap than to raise an exception.)






          share|improve this answer
























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54029372%2fmips-array-indexing-using-a-displacement-in-lw-for-a-known-constant-index%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            Both versions are logically correct; the only problem with the book version is that it's very inefficient.



            It fails to optimize based on the fact that 6 is an assemble-time constant, so the 6*4 can be an immediate displacement in the lw, instead of calculated at runtime in a register and added to the base separately.



            lw has room for 16 bits of immediate offset; it's silly not to take advantage and restrict yourself to only ever using 0. It's an I-type instruction for a reason, dedicating lots of coding space to allowing a large offset.



            Other than that your versions are equivalent. The book version calculates 6<<2 in a register and adds it to the base of B ($s2). It gets the initial 6 into a register by adding to the zero-register.



            Both yours and the book's use add instead of addu. Not sure why you want to trap on signed overflow, especially when doing address math. C compilers normally always use addu. (Signed overflow is undefined behaviour in C, but compiler developers know that it's usually more useful / expected for it to silently wrap than to raise an exception.)






            share|improve this answer




























              1














              Both versions are logically correct; the only problem with the book version is that it's very inefficient.



              It fails to optimize based on the fact that 6 is an assemble-time constant, so the 6*4 can be an immediate displacement in the lw, instead of calculated at runtime in a register and added to the base separately.



              lw has room for 16 bits of immediate offset; it's silly not to take advantage and restrict yourself to only ever using 0. It's an I-type instruction for a reason, dedicating lots of coding space to allowing a large offset.



              Other than that your versions are equivalent. The book version calculates 6<<2 in a register and adds it to the base of B ($s2). It gets the initial 6 into a register by adding to the zero-register.



              Both yours and the book's use add instead of addu. Not sure why you want to trap on signed overflow, especially when doing address math. C compilers normally always use addu. (Signed overflow is undefined behaviour in C, but compiler developers know that it's usually more useful / expected for it to silently wrap than to raise an exception.)






              share|improve this answer


























                1












                1








                1







                Both versions are logically correct; the only problem with the book version is that it's very inefficient.



                It fails to optimize based on the fact that 6 is an assemble-time constant, so the 6*4 can be an immediate displacement in the lw, instead of calculated at runtime in a register and added to the base separately.



                lw has room for 16 bits of immediate offset; it's silly not to take advantage and restrict yourself to only ever using 0. It's an I-type instruction for a reason, dedicating lots of coding space to allowing a large offset.



                Other than that your versions are equivalent. The book version calculates 6<<2 in a register and adds it to the base of B ($s2). It gets the initial 6 into a register by adding to the zero-register.



                Both yours and the book's use add instead of addu. Not sure why you want to trap on signed overflow, especially when doing address math. C compilers normally always use addu. (Signed overflow is undefined behaviour in C, but compiler developers know that it's usually more useful / expected for it to silently wrap than to raise an exception.)






                share|improve this answer













                Both versions are logically correct; the only problem with the book version is that it's very inefficient.



                It fails to optimize based on the fact that 6 is an assemble-time constant, so the 6*4 can be an immediate displacement in the lw, instead of calculated at runtime in a register and added to the base separately.



                lw has room for 16 bits of immediate offset; it's silly not to take advantage and restrict yourself to only ever using 0. It's an I-type instruction for a reason, dedicating lots of coding space to allowing a large offset.



                Other than that your versions are equivalent. The book version calculates 6<<2 in a register and adds it to the base of B ($s2). It gets the initial 6 into a register by adding to the zero-register.



                Both yours and the book's use add instead of addu. Not sure why you want to trap on signed overflow, especially when doing address math. C compilers normally always use addu. (Signed overflow is undefined behaviour in C, but compiler developers know that it's usually more useful / expected for it to silently wrap than to raise an exception.)







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jan 3 at 20:47









                Peter CordesPeter Cordes

                134k18203342




                134k18203342
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54029372%2fmips-array-indexing-using-a-displacement-in-lw-for-a-known-constant-index%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Monofisismo

                    Angular Downloading a file using contenturl with Basic Authentication

                    Olmecas