32位汇编:实验5算数运算类指令使用

1. 二进制数运算

(1)题目的具体要求,将原始数据及存放结果的内存单元分别定义成字变量或字节变量。

(2)编辑程序,把编写好的源程序建立为汇编语言源程序文件并存盘。

(3)对源程序文件进行汇编、连接,且修改至无错误,然后运行程序。

(4)利用调试程序观察运行结果。如果有错,分析并找出错误原因,改写程序并重新调试。

运行示例

复制代码
.386
.model flat, stdcall
option casemap:none

include windows.inc
include kernel32.inc
include user32.inc
include masm32.inc

includelib kernel32.lib
includelib user32.lib
includelib masm32.lib

	.data
	A DW 23579           
	B DW 7684            
	bC DB 0A5H 
	D DB 34H 
	E DW ?               
	G DB ? 

	fmt db "23579 + 7684 = %d", 13, 10
        db "0A5H + 34H = %02XH", 13, 10, 0
    buffer db 128 dup(0)

	.code
start:
	MOV ax,A
	ADD ax,B
	MOV E,ax
	
	MOV AL,bC
	ADD AL,D       
	MOV G,AL

	;结果格式化输出
	movzx EAX,G
	push EAX
	movzx EAX,E
	push EAX
	push offset fmt
	push offset buffer
	call wsprintf
	add esp,16

	push 0
	push offset caption
	push offset buffer
	push 0
	call MessageBoxA

	push 0
	call  ExitProcess
	
	caption DB "二进制运算结果",0

end start

我们发现编译为乱码,排查发现是源代码文件编码与系统期望的编码不匹配,更改文件编码后解决。

调试器进行验证

MOV ax,A

ADD ax,B

MOV E,ax

MOV AL,bC

ADD AL,D

MOV G,AL

经验证结果一致。

2. 多字节加法

(1)在FIRST和SECOND开始的内存单元中建立各为10位的压缩型BCD码的数据区,数据要选择得当。要考虑位间有进位和最高位也要有进位等不同情况。数据从低字节开始存放。

(2)把编写好的源程序,用编辑程序建立为汇编语言程序源文件并存盘。

(3)注意多字节运算加法指令的选择以及相应状态(如CF位)位的设置。进行BCD码运算时,要选择合适的十进制调节调整指令;运算结果的最高位进位情况要处理。

(4)汇编、连接源程序,且修改至无错误,然后运行程序。

知识回顾

多精度加法

多精度加法用于处理超过32位的整数运算(eg:64,128位甚至高精度整数)

因为寄存器最多为32位,因此需要分字节或分字处理,并手动处理CF(进位标志)

概念 说明
DAA 指令 加法后调整 AL 为压缩 BCD 格式(仅限 AL 寄存器)
ADC 指令 带进位加法,用于多字节加法
小端序 低位字节存在低地址,符合 x86 内存布局

压缩BCD

每字节含两位BCD数字

高4bit = 十位,低4bit = 个位,范围0-99(即0x00-0x99) • 示例:46H = 01000110b 表示BCD码46

运算后某位>9或半进位AC=1,必须立即DAA/DAS调整,否则报错。

  • 两个 10 位压缩 BCD 数(共 5 字节),低位在前
  • 相加后结果存入 THIRD,最多 11 位(6 字节,含进位)

x86 提供的十进制调整指令:

DAA ------ 加法后把 AL 调整为压缩 BCD(仅影响 AL,且只对 ADD/ADC 有效)。

DAS ------ 把AL调整成合法BCD,并减6校正。

这两条指令只认 AL,因此循环必须以字节为单位处理。

ADD后必须紧跟DAA,中间不能插入任何改变AL或标志的指令。

若CF=1表示向高位产生了进位(100以上)

运行示例

复制代码
	include io32.inc
	.data
FIRST DB 46H,58H,32H,71H,66H,0H 
SECOND DB 75H,21H,49H,23H,82H,0H
THIRD DB 6 DUP(?) 
	.code
start:
	MOV ECX,6
	MOV ESI,0
	CLC
LLO: 
    MOV AL,SECOND[ESI] 
	ADC AL,FIRST[ESI] 
	DAA
	MOV THIRD[ESI],AL
	INC ESI
	LOOP LLO
	exit 0
	end start

调试器验证

复制代码
MOV CX,6
MOV ESI,0
CLC

存储清零

复制代码
MOV AL,SECOND[ESI] 
ADC AL,FIRST[ESI] 
DAA
MOV THIRD[ESI],AL
INC ESI
LOOP LLO

第一次循环相加中出现了进位CF=1

第一次循环结束后cx-1,EIP进入第二次循环位置

此后循环依次执行,我们发现该代码并没有直接退出循环,问题为ECX≠0,我们只把CX置0,修改后程序正常6此后退出循环,得到我们相加后的数值

最终结果为014894818021,验证成功

3. 二进制乘法

(1)选择相应的数据存放于内存单元中。为了考查多种情况,数据选择要合理。对于8位无符号数应使其在0~255的范围内,并使得积大于8位无符号数的范围;对于16位有符号数的选择应兼顾到正、负数的情况。注意乘法指令的选择要考滤有符号乘法和无符号乘法的不同情况;有符号乘数如果为负数,则数据在内存中以二进制补码形式存放。

知识回顾

乘法指令一览

无符号

MUL r/m8 ; AX ← AL * r/m8

MUL r/m16 ; DX:AX ← AX * r/m16

MUL r/m32 ; EDX:EAX ← EAX * r/m32

有符号

IMUL r/m8 ; AX ← AL * r/m8

IMUL r/m16 ; DX:AX ← AX * r/m16

IMUL r/m32 ; EDX:EAX ← EAX * r/m32

规则:

  • 源操作数 × 累加器(AL/AX/EAX)→ 双倍宽度结果。
  • 结果高半部永远放在 AH/DX/EDX,低半部放在 AL/AX/EAX。
  • CF/OF 置位表示"高半部非 0(无符号)或符号扩展失败(有符号)",其他标志未定义。

8 位无符号要点

被乘数必须预先装 AL,乘数可为内存字节或寄存器。

结果 16 位,在 AX 中,直接 mov [mem],ax 即可。

16 位带符号要点

被乘数必须预先装 AX,乘数可为内存字或寄存器。

结果 32 位,高 16 位在 DX,低 16 位在 AX。由于 Win32 内存按 32 位对齐方便,可一次把 DX:AX 存到连续 4 字节。

符号扩展与高位丢弃若只关心完整 32 位结果,无需理会 CF/OF;若需 64 位结果,可用 32 位 IMUL 产生 EDX:EAX。

MASM32 内存声明字节用 db,字用 dw,双字用 dd;带符号十进制字面量直接写,如 -12345,MASM 会自动按 16 位补码编码。

运行示例

复制代码
	include io32.inc
	.data
	DATA1 DB 245 
	DATA2 DB 43 
	DATA3 DW ?
	FIRST DW 6405H 
	SECOND DW 0FFFEH 
	THIRD DW ?
	THIRD1 DW ?
	.code
start:
	MOV AL,DATA1
	MUL DATA2
	MOV DATA3,AX 
	MOV AX,FIRST
	IMUL SECOND
	MOV THIRD,AX
	MOV THIRD1,DX
	exit 0
	end start

调试器验证

无符号数

复制代码
MOV AL,DATA1
MUL DATA2

我们可以看出ax值正确

有符号乘法

复制代码
MOV AX,FIRST
IMUL SECOND

我们可以看出结果正确

相关推荐
ol木子李lo1 天前
Visual studio 2022高亮汇编(ASM)语法方法
汇编·ide·windows·visual studio
资料,小偿3 天前
4.1.1基于51单片机汇编语言出租车计价器可切换白天黑夜,可修改价格
汇编·51单片机·proteus
embrace993 天前
【C语言学习】数据在内存中存储
java·c语言·开发语言·汇编·c++·学习·算法
T.Ree.9 天前
汇编_mov指令
汇编
CC-NX9 天前
32位汇编:实验12动态链接库
汇编
资料,小偿10 天前
4.101基于8086国旗图案proteus8.9,8086彩灯图案流水灯图案,国期图案仿真,四个开关四种模式。近期本人原创
汇编·proteus
资料,小偿12 天前
4.29.3五种波形发生器8086波形发生器,锯齿波脉冲波正弦波三角波直流信号含调试视频➕18页5000字原创报告软件流程图proteus8.9近期原创的,
汇编·proteus
T.Ree.13 天前
汇编_读写内存
开发语言·汇编·c#
量子炒饭大师13 天前
【一天一个计算机知识】—— 【编程百度】翻译环境与运行环境
c语言·汇编·c++·gitee·机器翻译
资料,小偿15 天前
4.98基于8086倒车测距8086测距ACD0809proteus8.9仿真,汇编语言源程序
汇编·proteus