这一切都是相关的,我尽量按照逻辑将它们拼凑在一起,所以请多多包涵。
我真的很困惑如何正确处理标签。比如下面这段代码中,“bne”翻译成“00010101001001010000000000000001”,loopend的标签地址为0x00000020(32)
.text
la $a0, opOne
lw $a0, 0($a0)
la $a1, opTwo
lw $a1, 0($a1)
add $t0, $zero, $a0
addi $t1, $zero, 1
bne $t1, $a1, loopend
addi $t1, $t1, 1
loopend:
当我将 loopend 向上移动时,“bne”变为“00010101001001011111111111111011”并且 loopend 的地址变为 0x00000008 (8)
.text
la $a0, opOne
lw $a0, 0($a0)
loopend:
la $a1, opTwo
lw $a1, 0($a1)
add $t0, $zero, $a0
addi $t1, $zero, 1
bne $t1, $a1, loopend
addi $t1, $t1, 1
所以据我了解,在第一段代码中,loopend
在8条指令之后,所以它的地址是4*8=32=0x00000020。在第二位代码中,loopend
在两条指令之后,所以它的地址是4*2,即0x00000008。
但是,我不明白的是标签地址。如果我错了请纠正我:标签地址取决于标签相对于调用它的指令的位置。所以在第一段代码中,loopend
比bne
晚两行,所以不用翻转符号,它的地址是“0000000000000001”。在第二个 loopend
出现在 bne
之前,所以你翻转标志,它的地址变成“1111111111111011”。
我知道您将地址向左移动了 2 位,但我仍然很困惑。如果末尾没有两个 0,你是否只向左移动,比如第二个 loopend
?
我最紧迫的问题是:0000000000000001,loopend
的地址,在第一个 bne 机器语言翻译中来自哪里?我认为标签 loopend
的地址将是 0000000000100000。
最佳答案
BNE -- Branch on not equal
___________________________________________________________________________
|Description: | Branches if the two registers are not equal |
|_____________|_____________________________________________________________|
|Operation: | if $s != $t advance_pc (offset << 2)); else advance_pc (4); |
|_____________|_____________________________________________________________|
|Syntax: | bne $s, $t, offset |
|_____________|_____________________________________________________________|
|Encoding: | 0001 01ss ssst tttt iiii iiii iiii iiii |
|_____________|_____________________________________________________________|
对于第一个 bne,偏移量为 1,因此 1 << 2 = 4,因此您将程序计数器递增四个字节。由于字长为 32 位,因此 pc 增加一条指令
.text
la $a0, opOne
lw $a0, 0($a0)
la $a1, opTwo
lw $a1, 0($a1)
add $t0, $zero, $a0
addi $t1, $zero, 1
bne $t1, $a1, loopend
addi $t1, $t1, 1 # increment by 1 insruction
loopend: # to here (well the next instruction)
对于第二个 bne,偏移量是 b1111111111111011,符号扩展它的 -5 所以 -5 << 2 = -20 所以你将程序计数器递增 - 20 个字节或递减 20 个字节。由于字长为 32 位,因此 pc 递减了 5 条指令
.text
la $a0, opOne
lw $a0, 0($a0)
loopend: #
la $a1, opTwo # 5 to here
lw $a1, 0($a1) # 4 ^
add $t0, $zero, $a0 # 3 |
addi $t1, $zero, 1 # 2 |
bne $t1, $a1, loopend # 1 |
addi $t1, $t1, 1 # decrement by 5 instructions
关于assembly - MIPS 标签寻址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16285119/