Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange jump in MIPS assembly

Tags:

assembly

mips

I'm probably missing something really obvious here, but I've been going over this over and over and I'm decidedly stuck. In the code below, $8 is incremented only if $2 != $0. Now I double and triple checked and the beq instruction works (for example if I change lop to end2, it does go there).

However, for some reason, $8 is incremented regardless, even if the branch is executed.

lop:   beq $3, $0, end2
       and $2, $3, $4

       sll $3, $3, 1

       beq $2, $0, lop     

       addi $8, $8, 1

       j lop

I've got to admit I'm completely stumped.

like image 873
user472875 Avatar asked Dec 22 '22 21:12

user472875


2 Answers

(The and after the first beq will always be executed, too.)

MIPS has explicit pipeline hazards; by the time the decision to branch (or not) is made, the following instruction has already progressed far enough through the instruction pipeline that it will be executed regardless. This is known as the "branch delay slot".

In some cases you can arrange code to take advantage of this; if you can't (or don't want to), you can just put a nop in the following instruction.

Some assemblers will reorder code (or fill in the nop) for you - e.g. gas, the GNU assembler, does, unless you tell it not to with a .set noreorder directive. But you still need to be aware of it when disassembling anyway.

If you're writing code without automatic reordering by the assembler, I recommend annotating the delay slot with some extra indentation to make it stand out:

lop:   beq $3, $0, end2
         nop
       and $2, $3, $4

       sll $3, $3, 1

       beq $2, $0, lop     
         nop

       addi $8, $8, 1

       j lop
like image 169
Matthew Slattery Avatar answered Jan 08 '23 18:01

Matthew Slattery


The add instruction is occurring in the branch delay slot of the beq.

like image 20
Oliver Charlesworth Avatar answered Jan 08 '23 19:01

Oliver Charlesworth