組合語言與程序呼叫

虛擬指令

有些你想在組語裡寫的東西很常見,卻在精簡的指令集裡有點難表達。為了讓程式設計者舒服一點,組譯器提供了幾個方便的簡寫,看起來像真指令、其實不是:這就是虛擬指令(pseudo-instruction)。你寫親切的版本,組譯器再悄悄把它展開成一道或多道真正的機器指令。就像編輯器幫你自動展開的片語:你打一個縮寫,完整文字就跑出來。

RISC-V 裡的經典例子是 mv a0, a1(把暫存器 a1 的值搬到 a0)。真正的指令集裡並沒有專門的搬移指令;組譯器會把 mv a0, a1 變成 addi a0, a1, 0(把 a1 加零再存進 a0),效果相同。同樣地,li a0, 5(載入立即值)可能變成一道 addi,而載入一個大常數則可能展開成兩道指令。虛擬指令純粹是組譯器的便利;處理器從來看不到 mv 或 li,只看到它們展開成的真指令。

虛擬指令之所以重要,是因為它們在不增加任何硬體的前提下,大大提升了組語的可讀性。它們屬於組譯器的文件而非 ISA 的一部分,因此不同工具鏈之間可能有差異。當你閱讀反組譯(disassembly,把機器碼轉回文字)時,好的反組譯器常會顯示虛擬指令,讓輸出保持易讀。一個誠實的提醒:別把虛擬指令誤當成硬體功能。mv 是便利,addi 才是機器本身。

你寫的是: li t0, 42 # 載入常數 42 組譯器產生的是: addi t0, zero, 42 # 把 42 加到永遠為零的暫存器上 處理器實際執行的只有 addi;li 從不存在於機器碼中。

li 是虛擬指令;它會展開成一道真指令(大常數時會展開成兩道)。

虛擬指令屬於組譯器,不屬於 ISA。同一顆晶片的兩個組譯器可能提供不同的虛擬指令,而且它們不會帶來任何新的硬體能力。

又称
pseudo-op假指令