汇编语言基础: 搭建实验环境
环境配置
1.Visual Studio 创建空项目
- 创建成功
2.平台框架改为为WIN32
- 右键点击项目
- 点击属性
- 点击配置管理器
- 平台改为Win32(本文使用32位的汇编)
3.生成采用MASM
-
在项目属性里点击"生成依赖项"的"生成自定义"
-
勾选 masm
4.创建第一个汇编程序
- 右键源文件添加新建项,添加一个
.asm
结尾的文件
- 写下如下代码
.386
.model flat,stdcall
option casemap:none
.datax dd 2
.code
_main proc
start::push ebpmov ebp,esppop ebpxor eax,eaxret
_main endp
end start
- 打一个断点编译并调试(内存中x变量值为2)
- 如果没有内存图,点击上方调试,点击窗口的内存(同样也可以调出寄存器的)
简单程序编写
- 要求:编写程序,求
sum=x+y
,sum=x-y
,sum=x/y
,sum=x*y
的结果
.386 ; 使用386指令集
.model flat, stdcall ; 平坦内存模型,stdcall调用约定
option casemap:none ; 区分大小写.datax db 8 ; 定义字节变量x,值为8y db 4 ; 定义字节变量y,值为4sum db 0 ; 定义字节变量sum,初始值为0.code
_main proc
start::push ebp ; 保存基址指针mov ebp, esp ; 设置基址指针为当前栈指针; 1. 加法运算: sum = x + ymov al, x ; 将x的值(8)加载到AL寄存器add al, y ; AL = AL + y(8+4=12)mov sum, al ; 将结果(12)存入sum; 2. 减法运算: sum = x - ymov al, x ; 重新加载x的值到ALsub al, y ; AL = AL - y(8-4=4)mov sum, al ; 将结果(4)存入sum; 3. 乘法运算: sum = x * ymov al, x ; 加载x到ALmul y ; 乘法: AL * y → AX(8*4=32)mov sum, al ; 将结果的低8位(32)存入sum; 4. 除法运算: sum = x / ymov al, x ; 加载被除数x(8)mov ah, 0 ; 清除AH寄存器(高位)mov bl, y ; 加载除数y(4)div bl ; 除法: AX / BL → 商在AL(2),余数在AHmov sum, al ; 将商(2)存入sumpop ebp ; 恢复基址指针xor eax, eax ; 将eax清零(作为程序返回值)ret ; 返回
_main endp
end start ; 指定程序入口点
代码详解
-
数据段(.data)
x db 8
:定义8位字节变量x,初始值为8y db 4
:定义8位字节变量y,初始值为4sum db 0
:定义8位结果变量,初始化为0
-
代码段(.code)
push ebp
/mov ebp, esp
:标准函数开场,建立栈帧pop ebp
:函数结束前恢复栈帧
-
算术运算实现
-
加法:
mov al, x ; AL = 8 add al, y ; AL = 8 + 4 = 12 mov sum, al ; sum = 12
- 使用ADD指令实现加法,结果存入AL寄存器
-
减法:
mov al, x ; 重新加载x值(因AL已被修改) sub al, y ; AL = 8 - 4 = 4 mov sum, al ; sum = 4
- SUB指令实现减法,需注意寄存器值的覆盖问题
-
乘法:
mov al, x ; AL = 8 mul y ; AX = AL * y = 8 * 4 = 32 mov sum, al ; sum = AL = 32
- MUL指令执行无符号乘法
- 结果存储在AX(16位)中,AL包含低8位
-
除法:
mov al, x ; AL = 8(被除数低8位) mov ah, 0 ; AH = 0(被除数高8位) mov bl, y ; BL = 4(除数) div bl ; AL = AX/BL = 8/4 = 2(商) mov sum, al ; sum = 2
- DIV指令执行无符号除法
- 被除数必须在AX中(16位)
- 商存储在AL,余数在AH
-
-
程序退出
xor eax, eax
:将EAX清零,作为程序返回值ret
:从过程返回
调试技巧
- 在关键指令后设置断点(F9)
- 使用内存窗口(调试→窗口→内存)查看变量值
- 使用寄存器窗口(调试→窗口→寄存器)观察寄存器变化
- 单步执行(F10/F11)跟踪指令执行流程
注意事项
- 乘法结果可能超出8位(如本例中8*4=32仍在8位范围内)
- 除法前必须清除AH寄存器(16位除法)
- 连续运算时需注意寄存器值的覆盖问题
- Win32汇编使用平坦内存模型(flat),无分段概念
- 确保使用正确的调用约定(stdcall)