簡體   English   中英

MIPS匯編中的跳轉指令

[英]Jump instruction in MIPS Assembly

這是我為測試跳轉指令而編寫的一些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

當我運行匯編程序時,結果如下:

[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)

查看跳轉指令的機器代碼,這就是我所看到的:

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

通過查看這些指令,看起來機器代碼以跳轉指令的08開頭,最后的數字告訴跳轉指令去哪里。 但是,我無法弄清楚這個數字是如何計算出來的。 此外,沒有什么可以向我表明第五跳是向后跳躍。

如何計算跳躍值?

請查看參考手冊,了解有關操作碼編碼的更多詳細信息。

短版本:在32位指令中,您不能包含32位跳轉目標。 操作碼使用6位,為指令留下26位。 通過取j指令之后的指令地址的前4位構造目標地址,然后將2個零位附加到跳轉指令操作數的26位。 (由於指令是32位,對齊很有用,允許省略最后兩個0。)

向后跳轉:地址是絕對的,不是相對的,所以它只取決於跳轉指令的地址,無論是向前跳還是向后跳轉。

編輯 :更詳細的描述:我們在地址x跳轉指令j t代表j的跳躍操作數。 t是26位寬。 下一條指令的地址位模式計算如下:

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

所以跳躍總是絕對的。 沒有相對跳躍。 當結果小於x然后它是向后跳躍,當它更大時它是向前跳躍(並且如果你想要一些愚蠢的東西,你使它相等;-)。

那么讓我們來看看你的例子的第5跳:

跳轉目標的前6位是:000000,因為跳轉后面的指令的地址的高6位是000000。

接下來的26位是跳轉指令的最低26位,即00000000000000000000001000

最后2位是:00,因為始終附加。

我們一起有:0000000000000000000000000000100000,它是十六進制20.並且在該地址正是流應該繼續的標簽/指令。

在MIPS中, J是J型指令:

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

所以我們有一個26位長的target 它與下一條指令的PC結合如下:

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

它向左移位2位,因為MIPS指令(忽略MIPS16擴展)是32位長,這意味着它們都從低2位為零的地址開始。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM