x86 64架构汇编语言

3、数据类型与整数运算

1、课程目标

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

2、名词解释

术语 说明
BYTE 1字节 (db)
WORD 2字节 (dw)
DWORD 4字节 (dd)
QWORD 8字节 (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标志)。