Search code examples
assemblymipsgnu-assemblerbinutils

Weired behaviour of GNU AS on divu MIPS instruction


In order to test our MIPS implementation on a FPGA, I wrote a couple of assembler test code. I'm using mips-linux-gnu-as for compilation.

The following code is to test the divu implementation, from the code, the condition beq $t2, $t1, label1 is expected to pass and 3 is loaded in $t1.

.set noreorder
.text
__start:
    li  $t1, 10         
    li  $t2, 2

    divu $t1, $t2
    mflo $t2
    li $t1, 5
    beq $t2, $t1, label1
    j label2
label1:
    li  $t1, 3
label2:
    nop

My problem is that gnu-as is producing weird output for the above code, which ends in a different behaviour of the execution, and 3 is never loaded in $t1.

The diassembly of section .text

00000000 <__start>:
0:   2409000a        addiu   t1,zero,10
4:   240a0002        addiu   t2,zero,2
8:   15400002        bnez    t2,14 <__start+0x14>
c:   012a001b        divu    zero,t1,t2
10:   0007000d        break   0x7
14:   00004812        mflo    t1
18:   00005012        mflo    t2
1c:   24090005        addiu   t1,zero,5
20:   11490001        beq     t2,t1,28 <label1>
24:   0800000b        j       2c <label2>

00000028 <label1>:
28:   24090003        addiu   t1,zero,3

0000002c <label2>:
2c:   00000000        sll     zero,zero,0x0

Any help is greatly appreciated.


Solution

  • Branches and jumps may not occur in delay slots. You have j in beq's delay slot. Also, I don't think you want addiu t1, zero, 3 in j's delay slot either. You should probably use .set reorder instead of .set noreorder. Alternatively, you need to learn how to deal with branch delay slots.