[英]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.