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?