我不明白如何翻译标签。任何人都可以给我一个帮助
假设我们有以下代码:
loop:
add $t2,$t2,$t1
addi $t2,$t2,4
sw $t2,4($s0)
bne $t2,20,loop
jr $ra
如何转换为二进制bne $t2,10,loop
?
答案 0 :(得分:3)
有几点需要注意。
分支偏移总是根据分支地址+4(即PC + 4)计算,因此它相对于jr
指令的地址。
由于mips指令必须与字[四字节边界]对齐,因此指令地址的最右边两位将[必须始终为零]。
mips架构利用了将分支偏移编码为字偏移(即字节偏移右移2)的优点。这将分支指令16位立即编码的范围扩展到18位。
所以,这是列表:
00: loop:
00: add $t2,$t2,$t1
04: addi $t2,$t2,4
08: sw $t2,4($s0)
0C: bne $t2,20,loop
10: jr $ra
jr
地址为0x10
,因此循环的字节偏移量为-0x10,编码偏移量为-0x04或0xFFFC,bne
为xxxxFFFC
}
但......有一个问题。此特定bne
使用立即值作为第二个参数。这使bne
为伪操作,不为简单bne
指令。
因此,实际的序列变为:
00: loop:
00: add $t2,$t2,$t1
04: addi $t2,$t2,4
08: sw $t2,4($s0)
0C: addi $at,$zero,20
10: bne $at,$t2,loop
14: jr $ra
请注意,bne
成为两个指令序列:addi
和bne
jr
地址现在为0x14
,因此循环的字节偏移量为-0x14,编码偏移量为-0x05或0xFFFB,bne
为{{1} }}
xxxxFFFB
汇编程序格式为:
bne
bne s,t,label
编码为:
bne
因此,0001 01ss ssst tttt iiii iiii iiii iiii
注册表为s
或$at
- > $1
00001
注册为t
或$t2
- > $10
所以,现在我们有:
01010
在十六进制中,这是0001 01ss ssst tttt iiii iiii iiii iiii
00 0010 1010
0001 0100 0010 1010 iiii iiii iiii iiii
。我们已经知道142Ayyyy
为yyyy
,因此最终的十六进制值为:FFFB
答案 1 :(得分:0)
不相等的分支具有语法bne rs,rt,label
,其中前6位是操作码,接下来的5位是rs,接下来的5位是rt,其余是分支目标地址的标签:
BTA = PC + 4 + imm * 4
是通过符号扩展立即数,乘以4并将其和4加到程序计数器来计算的。有关解释,请参阅此问题
How to Calculate Jump Target Address and Branch Target Address?
bne
格式是立即的(I-type)。操作码是5(000101)。例如,此机器代码打印字母表中的每三个字符。
00100100000100000000000000110000
00000000000100000010000000100001
00100100000000100000000000001011
00000000000000000000000000001100
00100010000100000000000000000011
00100100000010000000000001011101
00010110000010001111111111111010
00000000000000000000000000000000
00001000000100000000000000001000
00000000000000000000000000000000
这是10行(10条指令)。第7行是一个分支,它有机器代码00010110000010001111111111111010
。前6个数字000101
是操作码5.然后是5 + 5位寄存器(在这个例子中,寄存器是$ 16和$ 8,其余的是直接分支目标地址。
同样,你的程序
.text
loop:
add $t2,$t2,$t1
addi $t2,$t2,4
sw $t2,4($s0)
bne $t2,20,loop
jr $ra
转换为7行机器代码:
00000001010010010101000000100000
00100001010010100000000000000100
10101110000010100000000000000100
00100000000000010000000000010100
00010100001010101111111111111011
00000011111000000000000000001000
实际翻译看起来像这样
Address Code Basic Source
0x00400000 0x01495020 add $10,$10,$9 3 add $t2,$t2,$t1
0x00400004 0x214a0004 addi $10,$10,0x00000004 addi $t2,$t2,4
0x00400008 0xae0a0004 sw $10,0x00000004($16)5 sw $t2,4($s0)
0x0040000c 0x20010014 addi $1,$0,0x00000014 6 bne $t2,20,loop
0x00400010 0x142afffb bne $1,$10,0xfffffffb
0x00400014 0x03e00008 jr $31 7 jr $ra
...倒数第二行的位置是bne
:00010100001010101111111111111011
。前6位000101
是操作码,接下来的5(00001
)+ 5(01010
)位是寄存器,其余(1111111111111011
)是立即值分支目标地址的格式(十六进制1111111111111011
= FFFB
。
有关详细信息,请参阅MIPS manual。