跳轉到內容

x86 彙編/移位和旋轉

來自華夏公益教科書,開放的書籍,開放的世界


邏輯移位指令

[編輯 | 編輯原始碼]

邏輯移位指令(也稱為無符號移位)中,從末尾移出的位會消失(除了最後一個位進入進位標誌),並且空格始終填充零。邏輯移位最適合用於無符號數。


shr cnt, dest GAS 語法
shr dest, cnt Intel 語法


dest邏輯右移cnt位。


shl cnt, dest GAS 語法
shl dest, cnt Intel 語法


dest邏輯左移cnt位。

示例 (GAS 語法)

movw   $ff00,%ax        # ax=1111.1111.0000.0000 (0xff00, unsigned 65280, signed -256) 
shrw   $3,%ax           # ax=0001.1111.1110.0000 (0x1fe0, signed and unsigned 8160)
                        # (logical shifting unsigned numbers right by 3
                        #   is like integer division by 8)
shlw   $1,%ax           # ax=0011.1111.1100.0000 (0x3fc0, signed and unsigned 16320) 
                        # (logical shifting unsigned numbers left by 1
                        #   is like multiplication by 2)

算術移位指令

[編輯 | 編輯原始碼]

算術移位(也稱為有符號移位)中,與邏輯移位類似,從末尾移出的位會消失(除了最後一個位進入進位標誌)。但在算術移位中,空格的填充方式會保留被移位數字的符號。因此,算術移位更適合於二進位制補碼格式的有符號數。


sar cnt, dest GAS 語法
sar dest, cnt Intel 語法


dest算術右移cnt位。空格用符號位(以保持原始值的符號)填充,即原始最高位。


sal cnt, dest GAS 語法
sal dest, cnt Intel 語法


dest算術左移cnt位。底部的位不會影響符號,因此底部位用零填充。此指令等同於 SHL。

示例 (GAS 語法)

movw   $ff00,%ax        # ax=1111.1111.0000.0000 (0xff00, unsigned 65280, signed -256)
salw   $2,%ax           # ax=1111.1100.0000.0000 (0xfc00, unsigned 64512, signed -1024)
                        # (arithmetic shifting left by 2 is like multiplication by 4 for
                        #   negative numbers, but has an impact on positives with most
                        #   significant bit set (i.e. set bits shifted out))
sarw   $5,%ax           # ax=1111.1111.1110.0000 (0xffe0, unsigned 65504, signed -32)
                        # (arithmetic shifting right by 5 is like integer division by 32
                        #   for negative numbers)

擴充套件移位指令

[編輯 | 編輯原始碼]

雙精度移位操作的名稱有些誤導,因此在本頁中它們被列為擴充套件移位指令。

它們可用於 16 位和 32 位資料實體(暫存器/記憶體位置)。src 運算元始終是暫存器,dest 運算元可以是暫存器或記憶體位置,cnt 運算元是立即位元組值或 CL 暫存器。在 64 位模式下,也可以定址 64 位資料。


shld cnt, src, dest GAS 語法
shld dest, src, cnt Intel 語法

shld 執行的操作是將 dest 中最重要的 cnt 位移出,但不是用零填充最低有效位,而是用 src 的最重要的 cnt 位填充。


shrd cnt, src, dest GAS 語法
shrd dest, src, cnt Intel 語法

類似地,shrd 操作將 dest 中最低有效的 cnt 位移出,並用 src 運算元的最低有效位填充最重要的 cnt 位。

英特爾的命名法具有誤導性,因為移位不作用於雙倍的基本運算元大小(即指定 32 位運算元不會使其成為 64 位移位):src 運算元始終保持不變。

此外,英特爾的參考手冊[1] 指出,當 cnt 大於運算元大小時,結果是未定義的,但至少對於 32 位和 64 位資料大小,已觀察到移位操作是透過 (cnt mod n) 執行的,其中 n 是資料大小。

示例 (GAS 語法)

xorw   %ax,%ax          # ax=0000.0000.0000.0000 (0x0000)
notw   %ax              # ax=1111.1111.1111.1111 (0xffff)
movw   $0x5500,%bx      # bx=0101.0101.0000.0000
shrdw  $4,%ax,%bx       # bx=1111.0101.0101.0000 (0xf550), ax is still 0xffff
shldw  $8,%bx,%ax       # ax=1111.1111.1111.0101 (0xfff5), bx is still 0xf550

其他示例(十進位制數用於解釋概念,而不是二進位制數

# ax = 1234 5678
# bx = 8765 4321
shrd   $3, %ax, %bx     # ax = 1234 5678 bx = 6788 7654
# ax = 1234 5678
# bx = 8765 4321
shld   $3, %ax, %bx     # bx = 5432 1123 ax = 1234 5678

旋轉指令

[編輯 | 編輯原始碼]

在旋轉指令中,從暫存器末尾移出的位會反饋到空格中。

ror offset, variable GAS 語法
ror variable, offset Intel 語法

variable右移offset位。以下是這種操作的圖形表示

            ╭──────────────────╮
%al old     │ 0 0 1 0'0 1 1 1  │
ror 1, %al  ╰─╮╲ ╲ ╲ ╲ ╲ ╲╰─╯
%al new       1 0 0 1'0 0 1 1

旋轉位數offset被掩碼到最低 5 位(或在 64 位模式下為 6 位)。這等同於 操作,即整數除法的餘數(注意:)。這意味著,你永遠無法進行一次或多次“完整”旋轉。

運算元

[編輯 | 編輯原始碼]
  • Variable 必須是暫存器或記憶體位置。
  • Offset 可以是
    • 立即值(其中值 1 有一個專門的操作碼),
    • 或者 cl 暫存器(即 ecx 的最低位元組)。

修改的標誌

[編輯 | 編輯原始碼]

ror 僅在掩碼後的 offset零時才會改變標誌。 CF 變成最近旋轉的位,因此在 ror 的情況下,resultMSB(“符號”。

此外,如果掩碼後的 offset = 1,OF ≔ result[MSB] ⊻ result[MSB−1],因此 OF 告訴我們“符號”是否發生了變化。

rol offset, variable GAS 語法
rol variable, offset Intel 語法


variable左移offset位。

運算元和修改的標誌與 ror 相差無幾。但是,在掩碼後的 offset = 1 的情況下,OF 的定義不同,儘管實際上意義相同。對於 rol 1, xOF ≔ result[MSB] ⊻ result[LSB]。

請注意,在 rol 的情況下,CF 包含 LSB

帶進位的旋轉指令

[編輯 | 編輯原始碼]

類似於移位操作,旋轉操作可以使用進位位作為它移位的“額外”位。


rcr cnt, dest GAS 語法
rcr dest, cnt Intel 語法


dest向右旋轉cnt位,並使用進位位。


rcl cnt, dest GAS 語法
rcl dest, cnt Intel 語法


dest向左旋轉cnt位,並使用進位位。

引數數量

[編輯 | 編輯原始碼]

除非另有說明,這些指令可以接受一個或兩個引數。如果只提供一個引數,則假定它是暫存器或記憶體地址,並且要移位/旋轉的位數為1(但是,這可能取決於使用的彙編器)。 shrl $1, %eax 等效於 shrl %eax (GAS 語法)。

華夏公益教科書