Comportamiento extraño del ensamblador MIPS con instrucciones de salto (y enlace)

Entonces, estamos estudiando la arquitectura MIPS en la escuela y estamos implementando una arquitectura MIPS32. Pensé que usaría GNU cross-binutils como ensamblador, pero obtengo resultados extraños cuando trato con las instrucciones jal, j y jr. El ensamblador parece insertar las instrucciones en los lugares equivocados. No tengo idea de por qué sucede esto, y dudo que el ensamblador de MIPS esté tan roto, así que supongo que esto debería suceder.

Aquí está mi archivo de ensamblaje ficticio:

.section .text
.globl __start

__start:
   addi $a0, $0, 100
   addi $a1, $0, 200 
   jal test

test:
   add $v0, $a0, $a1
   jr $ra

Sin embargo, cuando desmonto obtengo esta salida:

Disassembly of section .text:

00000000 <__start>:
   0:   20040064    addi    a0,zero,100
   4:   0c000003    jal c <test>    <--- Why is jal coming before addi?
   8:   200500c8    addi    a1,zero,200

0000000c <test>:
   c:   03e00008    jr  ra  <--- Why is jr coming before add?
  10:   00851020    add v0,a0,a1
    ...

¿Es esto un capricho arquitectónico? Si es así, ¿cuál es la razón detrás de esto?

EDITAR: Probado agregando algunos nop solo por el gusto ...

.section .text
.globl __start

__start:
   addi $a0, $0, 100
   addi $a1, $0, 200 
   nop
   jal test

test:
   add $v0, $a0, $a1
   nop
   jr $ra

y me da algo que parece algo correcto.

Disassembly of section .text:

00000000 <__start>:
   0:   20040064    addi    a0,zero,100
   4:   200500c8    addi    a1,zero,200
   8:   0c000004    jal 10 <test>
   c:   00000000    nop

00000010 <test>:
  10:   00851020    add v0,a0,a1
  14:   03e00008    jr  ra
  18:   00000000    nop
  1c:   00000000    nop

¿Por qué jal y j intercambian lugares con la última instrucción?

Respuestas a la pregunta(1)

Su respuesta a la pregunta