x86 64架构汇编语言

4、位运算指令

1、课程目标

  • 掌握汇编中的位运算指令
  • 理解移位指令和循环移位
  • 掌握TEST和BT系列指令
  • 了解位操作在安全编程中的应用

2、名词解释

指令 说明
AND 按位与
OR 按位或
XOR 按位异或
NOT 按位取反
SHL/SAL 左移
SHR 逻辑右移
SAR 算术右移
ROL/ROR 循环移位
TEST 测试位(不保存结果)
BT/BTS/BTR 位测试/设置/清除

3、代码实现

1. 基本位运算

.code
BitOps PROC
    ; AND - 按位与
    mov eax, 0FFh
    and eax, 0Fh        ; EAX = 0Fh (保留低4位)
    
    ; OR - 按位或
    mov eax, 0F0h
    or eax, 0Fh         ; EAX = FFh (设置低4位)
    
    ; XOR - 按位异或
    mov eax, 0FFh
    xor eax, 0Fh        ; EAX = F0h (翻转低4位)
    xor eax, eax        ; EAX = 0 (快速清零)
    
    ; NOT - 按位取反
    mov eax, 0
    not eax             ; EAX = FFFFFFFFh
    
    ret
BitOps ENDP

2. 移位指令

.code
ShiftOps PROC
    ; SHL - 逻辑左移 (乘以2)
    mov eax, 1
    shl eax, 4          ; EAX = 16 (1 << 4)
    
    ; SHR - 逻辑右移 (无符号除以2)
    mov eax, 16
    shr eax, 2          ; EAX = 4 (16 >> 2)
    
    ; SAR - 算术右移 (有符号除以2)
    mov eax, -16
    sar eax, 2          ; EAX = -4 (保持符号)
    
    ; ROL - 循环左移
    mov eax, 80000001h
    rol eax, 1          ; EAX = 00000003h
    
    ; ROR - 循环右移
    mov eax, 00000003h
    ror eax, 1          ; EAX = 80000001h
    
    ret
ShiftOps ENDP

3. 位测试指令

.code
BitTest PROC
    ; TEST - 测试位
    mov eax, 0101b
    test eax, 0001b     ; ZF=0 (位0为1)
    jnz bit0_set
    
    test eax, 0010b     ; ZF=1 (位1为0)
    jz bit1_clear
    
    ; BT - 位测试 (结果到CF)
    mov eax, 0Fh
    bt eax, 2           ; CF=1 (位2为1)
    jc bit2_set
    
    ; BTS - 位测试并设置
    mov eax, 0
    bts eax, 5          ; CF=0 (原为0), EAX=20h (设置位5)
    
    ; BTR - 位测试并清除
    mov eax, 0FFh
    btr eax, 3          ; CF=1 (原为1), EAX=F7h (清除位3)
    
    ; BTC - 位测试并翻转
    mov eax, 0
    btc eax, 7          ; CF=0, EAX=80h (翻转位7)
    
bit0_set:
bit1_clear:
bit2_set:
    ret
BitTest ENDP

4. C语言示例

#include <stdio.h>

int main() {
    printf("=== 位运算指令 ===\n\n");
    
    unsigned int flags = 0;
    unsigned int bitPos = 5;
    unsigned int result;
    
    // 设置位
    __asm {
        mov eax, flags
        bts eax, bitPos     ; 设置第5位
        mov result, eax
    }
    printf("设置位5后: 0x%X\n", result);
    
    // XOR加密
    unsigned char data[] = {0x48, 0x65, 0x6C, 0x6C, 0x6F};
    unsigned char key = 0x5A;
    
    printf("\nXOR加密:\n原始: ");
    for (int i = 0; i < 5; i++) printf("%02X ", data[i]);
    
    // 汇编XOR加密
    for (int i = 0; i < 5; i++) {
        __asm {
            mov al, data[i]
            xor al, key
            mov data[i], al
        }
    }
    
    printf("\n加密: ");
    for (int i = 0; i < 5; i++) printf("%02X ", data[i]);
    printf("\n");
    
    return 0;
}

5、课后作业

5.1、作业1:实现位操作宏

用汇编实现SET_BIT/CLEAR_BIT/TOGGLE_BIT。

5.2、作业2:XOR加密

实现一个完整的XOR字符串加密解密函数。