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?