Comportamento estranho do assembler MIPS com instruções de salto (e link)

Então, estamos estudando a arquitetura MIPS na escola e estamos implementando uma arquitetura MIPS32. Eu pensei em usar o GNU cross-binutils como assembler, mas estou obtendo uma saída estranha ao lidar com as instruções jal, j e jr. O montador parece inserir as instruções nos lugares errados. Não tenho idéia do por que isso acontece, e duvido que o assembler do MIPS esteja quebrado, então suponho que isso deva acontecer.

Aqui está o meu arquivo de montagem fictícia:

.section .text
.globl __start

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

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

No entanto, quando desmonte, recebo esta saída:

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
    ...

Isso é uma peculiaridade arquitetônica? Se sim, qual é a lógica por trás disso?

EDIT: Testado adicionando alguns nop's apenas para o diabo ...

.section .text
.globl __start

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

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

e isso me dá algo que parece um pouco correto.

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 que jal e j estão trocando de lugar com a última instrução?

questionAnswers(1)

yourAnswerToTheQuestion