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标志)。