以此题为例,讲解汇编的加减乘除的用法
data segment
V1 DQ 0D989AE3F35A004EH
V2 DQ 0100E2A5F228DD90H
SUM DQ ?
DIFF DQ ?
V3 DW 8001H
V4 DW 4002H
PRODUCT DD ?,?,?,?,?
QUOTIENT DW 0,1,1,1,1,1,1
data ends
code segment
assume cs:code, ds:data
start:
mov ax, data
mov ds, ax
; 64位无符号数加法 V1 + V2
; ...(此处省略加法代码,与之前提供的一致)
; 64位无符号数减法 V1 - V2
; ...(此处省略减法代码,与之前提供的一致)
; 16位无符号数乘法 V3 * V4
mov ax, [V3]
mul word ptr [V4] ; 结果在 dx:ax
mov word ptr [PRODUCT], ax ; 保存结果的低16位
mov word ptr [PRODUCT+2], dx ; 保存结果的高16位
; 16位有符号数乘法 V3 * V4
mov ax, [V3] ; 加载 V3
imul word ptr [V4] ; 有符号乘法 V3 * V4,结果在 dx:ax
mov word ptr [PRODUCT+6], ax ; 保存结果的低16位
mov word ptr [PRODUCT+8], dx ; 保存结果的高16位
; 16位无符号数除法 V3 / V4
xor dx, dx ; 清除 dx 以避免错误
mov ax, [V3]
div word ptr [V4] ; 商在 ax,余数在 dx
mov word ptr [QUOTIENT], ax ; 保存商
mov word ptr [QUOTIENT+2], dx ; 保存余数
; 结束程序
mov ax, 4C00H
int 21H
code ends
end start
- 加法(Addition)
在汇编语言中,加法是最基本的算术操作之一。它用于将两个数值相加。对于64位数值,需要逐部分进行加法,因为x86寄存器是16位的。
概念:
寄存器:CPU中的寄存器用于存储数据。在x86架构中,常见的通用寄存器包括AX, BX, CX, DX等。
进位(Carry):当两个数值相加的结果超过寄存器的宽度时,进位标志(Carry Flag, CF)会被设置。
操作:
add指令用于执行加法操作,将两个操作数相加,结果存储在第一个操作数指定的寄存器或内存位置。
adc(Add with Carry)指令用于在加法操作中包含前一次操作的进位。
; 64位无符号数加法 V1 V2
mov ax, word ptr[V1] ; 加载 V1 的低16位到 ax
mov bx, word ptr[V2] ; 加载 V2 的低16位到 bx
add ax, bx ; ax = ax + bx
mov word ptr[SUM], ax ; 存储结果的低16位
mov ax, word ptr[V1+2] ; 加载 V1 的次低16位到 ax
mov bx, word ptr[V2+2] ; 加载 V2 的次低16位到 bx
adc ax, bx ; ax = ax + bx + 进位
mov word ptr[SUM+2], ax ; 存储结果的次低16位
; 重复上述步骤,处理剩余的高位部分,使用 adc 考虑进位
; ...
- 减法(Subtraction)
减法操作用于从第一个操作数中减去第二个操作数。
概念:
借位(Borrow):当被减数小于减数时,需要从更高位借位,类似于十进制中的借位。
操作:
sub指令用于执行减法操作,将第二个操作数从第一个操作数中减去,结果存储在第一个操作数指定的寄存器或内存位置。
sbb(Subtract with Borrow)指令用于在减法操作中包含前一次操作的借位。
; 64位无符号数减法 V1 V2
mov ax, word ptr[V1] ; 加载 V1 的低16位到 ax
mov bx, word ptr[V2] ; 加载 V2 的低16位到 bx
sub ax, bx ; ax = ax - bx
mov word ptr[DIFF], ax ; 存储结果的低16位
mov ax, word ptr[V1+2] ; 加载 V1 的次低16位到 ax
mov bx, word ptr[V2+2] ; 加载 V2 的次低16位到 bx
sbb ax, bx ; ax = ax - bx - 借位
mov word ptr[DIFF+2], ax ; 存储结果的次低16位
; 重复上述步骤,处理剩余的高位部分,使用 sbb 考虑借位
; ...
- 乘法(Multiplication)
乘法操作用于计算两个数值的乘积。
概念:
乘法结果大小:在8086架构中,乘法的结果可能比操作数大。例如,两个16位数值相乘的结果可能是32位的。
操作:
mul指令用于执行**无符号乘法操作。**它将一个操作数与AX寄存器中的值相乘,结果存储在DX:AX(对于16位乘法)或EDX:EAX(对于32位乘法)寄存器对中。
在8086中,16位乘法的结果可以存储在32位寄存器对 dx:ax 中。
; 16位无符号数乘法 V3 V4
mov ax, V3 ; 加载 V3 到 ax
mov bx, V4 ; 加载 V4 到 bx
mul bx ; dx:ax = ax * bx
mov word ptr[PRODUCT], ax ; 存储结果的低16位
mov word ptr[PRODUCT+2], dx ; 存储结果的高16位
在8086汇编语言中,对于16位有符号数的乘法,确实使用 imul 指令而不是 mul。imul 指令支持有符号数的乘法,并且能够正确处理符号位。
; 16位有符号数乘法 V3 * V4
mov ax, [V3] ; 加载 V3
imul word ptr [V4] ; 有符号乘法 V3 * V4,结果在 dx:ax
mov word ptr [PRODUCT+6], ax ; 保存结果的低16位
mov word ptr [PRODUCT+8], dx ; 保存结果的高16位
- 除法(Division)
除法操作用于计算两个数值的商和余数。
概念:
除数和被除数:在除法操作中,被除数是要被分割的数,而除数是分割的量。
商和余数:除法的结果包括商(结果)和余数。
操作:
div指令用于执行无符号除法操作。它将DX:AX(对于16位除法)或EDX:EAX(对于32位除法)寄存器对中的值除以指定的操作数,商存储在AX,余数存储在DX。
; 16位无符号数除法 V3 / V4
xor dx, dx ; 清零 dx,确保 dx:ax 是32位被除数
mov ax, V3 ; 加载 V3 到 ax
mov bx, V4 ; 加载 V4 到 bx
div bx ; ax = dx:ax / bx,dx = dx:ax % bx
mov word ptr[QUOTIENT], ax ; 存储商
mov word ptr[QUOTIENT+2], dx ; 存储余数