简体   繁体   English

MIPS汇编中的跳转指令

[英]Jump instruction in MIPS Assembly

Here is some MIPS assembly code I wrote to test the jump instruction: 这是我为测试跳转指令而编写的一些MIPS汇编代码:

addi $a0, $0, 1
j next
next:
j skip1
add $a0, $a0, $a0
skip1:
j skip2:
add $a0, $a0, $a0
add $a0, $a0, $a0
skip2:
j skip3
loop:
add $a0, $a0, $a0
add $a0, $a0, $a0
add $a0, $a0, $a0
skip3:
j loop

When I run the assembler, here's the result: 当我运行汇编程序时,结果如下:

[0x000000]  0x20040001  # addi $a0, $zero, 1 ($a0 = 1)
[0x000004]  0x08000002  # j 0x0002 (jump to addr 0x0008)
[0x000008]  0x08000004  # j 0x0004 (jump to addr 0x0010)
[0x00000C]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x000010]  0x08000007  # j 0x0007 (jump to addr 0x001C)
[0x000014]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x000018]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x00001C]  0x0800000B  # j 0x000B (jump to addr 0x002C)
[0x000020]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x000024]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x000028]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x00002C]  0x08000008  # j 0x0008 (jump to addr 0x0020)

Looking at the machine code for the jump instructions, this is what I see: 查看跳转指令的机器代码,这就是我所看到的:

1st jump (just jumps to next instruction) 0x08000002
2nd jump (skips 1 instruction) 0x08000004
3rd jump (skips 2 instructions) 0x08000007
4th jump (skips 3 instructions) 0x0800000B
5th jump (skips 3 instructions backwards) 0x08000008

From looking at these instructions, it looks like the machine code starts with a 08 for the jump instruction, and the number at the end tells the jump instruction where to go. 通过查看这些指令,看起来机器代码以跳转指令的08开头,最后的数字告诉跳转指令去哪里。 However, I can not figure out how this number is calculated. 但是,我无法弄清楚这个数字是如何计算出来的。 Also, there is nothing to indicate to me that the 5th jump is a backwards jump. 此外,没有什么可以向我表明第五跳是向后跳跃。

How is the jump value calculated? 如何计算跳跃值?

Just look into a reference manual for more details about the opcode encoding. 请查看参考手册,了解有关操作码编码的更多详细信息。

Short version: In a 32 bit instruction you can not include a 32-bit jump destination. 短版本:在32位指令中,您不能包含32位跳转目标。 The opcode uses 6 bits, which leaves 26 bits for the instruction. 操作码使用6位,为指令留下26位。 The target address is constructed by taking the first 4 bits of the address of the instruction following the j instruction, then 2 zero bits are appended to the 26 bits from the jump instruction operand. 通过取j指令之后的指令地址的前4位构造目标地址,然后将2个零位附加到跳转指令操作数的26位。 (As the instructions are 32 bits, alignment is useful and allows the omitting of the last two 0's.) (由于指令是32位,对齐很有用,允许省略最后两个0。)

To the backward jump: The addresses are absolute, NOT relative, so it only depends on the address of the jump instruction, whether it is a forward or a backward jump. 向后跳转:地址是绝对的,不是相对的,所以它只取决于跳转指令的地址,无论是向前跳还是向后跳转。

EDIT : More detailed description: We have at address x jump instruction j . 编辑 :更详细的描述:我们在地址x跳转指令j Let t represent the jump operand of j . t代表j的跳跃操作数。 t is 26 bit wide. t是26位宽。 The bit pattern of address of the next instruction is computed as follows: 下一条指令的地址位模式计算如下:

upper_6_bits_of(x+4),t,0,0

So the jump is ALWAYS absolute. 所以跳跃总是绝对的。 There are no relative jumps. 没有相对跳跃。 when the result is smaller than x then it is a backward jump, when it is greater it is a forward jump (and if you want something stupid, you make it equal ;-). 当结果小于x然后它是向后跳跃,当它更大时它是向前跳跃(并且如果你想要一些愚蠢的东西,你使它相等;-)。

So let's look at the 5th jump of your example: 那么让我们来看看你的例子的第5跳:

The first 6 bits of the jump target are: 000000, because the upper 6 bits of the address of the instruction behind the jump are 000000. 跳转目标的前6位是:000000,因为跳转后面的指令的地址的高6位是000000。

The next 26 bits are the lowest 26 bits of the jump instruction, that is 00000000000000000000001000 接下来的26位是跳转指令的最低26位,即00000000000000000000001000

The last 2 bits are: 00, because the got always appended. 最后2位是:00,因为始终附加。

Together we have: 0000000000000000000000000000100000, which is hex 20. And at that address is exactly the label/instruction where the flow should continue. 我们一起有:0000000000000000000000000000100000,它是十六进制20.并且在该地址正是流应该继续的标签/指令。

In MIPS, J is a J-type instruction: 在MIPS中, J是J型指令:

J-type instructions (Jumps)
3    22
1    65                        0
+----+-------------------------+
| op |         target          |
+----+-------------------------+

So we have a target that is 26-bits long. 所以我们有一个26位长的target It gets combined with the PC of the next instruction as follows: 它与下一条指令的PC结合如下:

I
I+1 PC <- (PC & 0xf0000000) | (target << 2)

It is shifted left 2 bits, since MIPS instructions (ignoring the MIPS16 extension) are 32-bits long, meaning they all start in an address whose lower 2 bits are zero. 它向左移位2位,因为MIPS指令(忽略MIPS16扩展)是32位长,这意味着它们都从低2位为零的地址开始。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM