組合語言與 CPU

助憶符、運算元與定址模式

/ mnemonic: nuh-MON-ik /

讀一行組合語言,你會看到兩類東西:一個說明要做什麼的短字,接著是要對之動作的對象。那個短字是助憶符——某項操作好記的縮寫,像 mov(搬移)、add(加)、cmp(比較)或 jmp(跳躍)。它所作用的對象則是運算元。所以 mov rax, 5 讀作「助憶符 mov,運算元為 rax 與 5」。

運算元有幾種形式,而一個運算元如何指名它的值,稱為它的定址模式。立即運算元是直接烤進指令裡的常數——mov rax, 5 裡的 5。暫存器運算元指名一個暫存器,像 rax,意思是「該暫存器當前的值」。記憶體運算元指名記憶體中的一個位置,意思是「這個位址處的值」;位址可以有好幾種給法,常見的一種是基底加位移,寫成像 [rbp-8],意思是「rbp 裡的位址,減 8」。更精緻的記憶體模式會加上索引暫存器與比例,如 [rbx + rcx*4],這正是對一個 int 陣列(每個元素 4 位元組)做索引的表達方式。

這些零件是每條指令的文法。一眼認出某運算元是立即值、暫存器還是記憶體參考——並讀懂 [基底 + 索引*比例 + 位移]——就是跟上反組譯所需的大部分功夫。定址模式也正是高階構造現形之處:陣列索引變成帶比例索引的記憶體運算元,結構欄位存取變成一個位移,指標解參考變成像 [rax] 這樣單純的暫存器間接存取。

在 mov eax, [rbx + rcx*4 + 8] 中,助憶符是 mov,來源運算元是一個記憶體參考,讀自位址 rbx + rcx*4 + 8——這正是結構裡 arr[i] 的樣子。

助憶符=做什麼;運算元=對什麼做;定址模式=每個運算元如何指名它的值。

運算元外的方括號代表「這個位址處的記憶體」(一次解參考),而裸的暫存器代表暫存器本身的值——混淆這兩者是閱讀組合語言最常見的單一錯誤。可用的定址模式因 ISA 而異:像 AArch64 這種 RISC 提供的遠比 x86-64 少。

又称
opcode mnemonicaddressing mode助記符定址方式