x86 64架构汇编语言

3、数据类型与整数运算

1、课程目标

  • 掌握汇编中的数据类型
  • 理解有符号和无符号整数
  • 掌握加减乘除指令
  • 了解溢出和进位

2、名词解释

术语说明
BYTE1字节 (db)
WORD2字节 (dw)
DWORD4字节 (dd)
QWORD8字节 (dq)
进位标志CF, 运算结果溢出
溢出标志OF, 有符号溢出
符号标志SF, 结果为负
零标志ZF, 结果为零

3、代码实现

1. 数据定义

.data
    ; 字节 (1 byte)
    byteVar     db  255         ; 0-255 或 -128 到 127
    byteArray   db  1, 2, 3, 4, 5
    
    ; 字 (2 bytes)
    wordVar     dw  65535       ; 0-65535
    
    ; 双字 (4 bytes)
    dwordVar    dd  0FFFFFFFFh
    
    ; 四字 (8 bytes)
    qwordVar    dq  0123456789ABCDEFh
    
    ; 字符串
    szText      db  "Hello", 0
    
    ; 未初始化
.data?
    buffer      db  256 dup(?)

2. 加法和减法

.code
Arithmetic PROC
    ; ADD - 加法
    mov eax, 100
    add eax, 50         ; EAX = 150
    
    ; ADC - 带进位加法
    mov eax, 0FFFFFFFFh
    mov edx, 0
    add eax, 1          ; EAX = 0, CF = 1
    adc edx, 0          ; EDX = 1 (64位加法)
    
    ; SUB - 减法
    mov eax, 100
    sub eax, 30         ; EAX = 70
    
    ; SBB - 带借位减法
    ; 用于64位减法
    
    ; NEG - 取负
    mov eax, 100
    neg eax             ; EAX = -100 (0xFFFFFF9C)
    
    ; INC/DEC - 自增/自减
    mov ecx, 10
    inc ecx             ; ECX = 11
    dec ecx             ; ECX = 10
    
    ret
Arithmetic ENDP

3. 乘法和除法

.code
MulDiv PROC
    ; MUL - 无符号乘法
    ; 赋值EAX,结果在EDX:EAX
    mov eax, 100
    mov ebx, 10
    mul ebx             ; EDX:EAX = 1000
    
    ; IMUL - 有符号乘法
    mov eax, -10
    imul eax, 5         ; EAX = -50
    
    ; 三操作数形式
    imul ecx, eax, 3    ; ECX = EAX * 3
    
    ; DIV - 无符号除法
    ; 被除数在EDX:EAX
    mov edx, 0
    mov eax, 100
    mov ecx, 7
    div ecx             ; EAX=商(14), EDX=余数(2)
    
    ; IDIV - 有符号除法
    mov eax, -100
    cdq                 ; 符号扩展到EDX:EAX
    mov ecx, 7
    idiv ecx            ; EAX=商(-14), EDX=余数(-2)
    
    ret
MulDiv ENDP

4. C语言验证

#include <stdio.h>

int main() {
    printf("=== 汇编整数运算 ===\n\n");
    
    int a = 100, b = 7;
    int quotient, remainder;
    
    __asm {
        mov eax, a
        cdq             ; 符号扩展
        mov ecx, b
        idiv ecx
        mov quotient, eax
        mov remainder, edx
    }
    
    printf("%d / %d = %d%d\n", a, b, quotient, remainder);
    
    // 64位乘法结果
    unsigned int x = 0xFFFFFFFF;
    unsigned int y = 2;
    unsigned int high, low;
    
    __asm {
        mov eax, x
        mov ebx, y
        mul ebx
        mov low, eax
        mov high, edx
    }
    
    printf("\n0x%X * %d = 0x%08X%08X\n", x, y, high, low);
    
    return 0;
}

5、课后作业

5.1、作业1:计算平均值

用汇编实现数组平均值计算。

5.2、作业2:检测溢出

实现加法并检测溢出(检查CF/OF标志)。