加法运算主要包含ADD、ADC和INC三条指令,除INC不影响进位标志CF外,其他指令按照定义影响全部状态标志位, 即按照运算结果相应设置各个状态标志为0或1。
1. 加法指令ADD
加法指令 ADD 使目的操作数加上源操作数,和的结果送到目的操作数。
格式如下:
ADD reg,imm/reg/mem;加法:reg-reg+imm/reg/mem
ADD mem,imm/reg:加法:memmem+imm/reg
它支持寄存器与立即数、 寄存器、 存储单元, 以及存储单元与立即数、 寄存器间的加法运算, 按照定义影响6个状态标志位。 例如:
mov eax,Oaaff7348h;EAX=AAFF7348H,不影响标志
add al,27h;AL=AL+27H=48H+27H=6FH,所以EAX=AAFF736FH
:状态标志:OF=0,SF=0,ZF= 0,PF=1,CF=0
add ax,3fffh;AX=AX+3FFFH=736FH+3FFFH=B36EH,所以EAX=AAFFB36EH
;状态标志:OF=1,SF=1,ZF=0,PF=0,CF=0
add eax,88000000;EAX=EAX +88000000H=AAFFB36EH+88000000H=[1]32FFB36EH
;状态标志OF=1,SF=0,ZF=0,PF=0,CF=1
算术运算类指令既可以进行8位运算也可以进行16位和32位运算。 对于8位运算指令, 状态标志反映8位运算结果的状态; 同样, 进行16位或32位运算, 状态标志 (除PF) 也是反映16位或32位运算结果的状态。 例如, 进位 CF 标志在进行8 位加法时反映最高位 D, 的向上进位,而进行32位加法时则反映最高位D.,的进位。
2.带进位加法指令ADC
带进位加法指令ADC (Add with Carry) 除完成ADD加法运算外, 还要加上进位CF, 结果送到目的操作数, 按照定义影响6个状态标志位。 格式如下:
ADC reg, imm/reg/mem;带进位加法:reg=reg+imm/reg/mem+CF
ADC mem, imm/reg;带进位加法:mem=mem+imm/reg+CF
ADC指令用于与ADD指令相结合实现高精度数的加法。IA-32处理器可以实现32位加法。但是, 多于32位的数据相加就需要先将两个操作数的低32位相加 (用ADD指令), 然后再加高位部分, 并将进位加到高位 (需要用ADC指令)。
[例] 64位数据相加程序
;数据段
qvar1 qword 6778300082347856h;64位数据1
qvar2 qword 6776200082348998h:64位数据2
;代码段
mov eax, dword ptr qvar1;取低32位
add eax, dword ptr qvar;加低32位,设置CF
mov edx,dword ptr qvarl +4;取高32位
adc edx,dword ptr qvar2 +4;加高32位,同时也加上CF
call disprd
本示例程序实现两个64位整数相加, 和值保存在EDX (高32位) 和EAX (低32位) 寄存器对中。 64位数据用4字变量定义QWORD, 先加低32位 (ADD指令), 再加高32位 (ADC指令) 进行高32位加法时, 需要加上低32位相加形成的进位标志CF, 所以使用了带进位的加法指令.MOV指令不影响任何状态标志, 所以执行 ADC指令时使用的 CF 就是前面 ADD指令设置的状态。 与32位寄存器配合, 具有64位属性的变量需要进行强制类型转换, 用 “DWORD PTRQVARI" 指向低32位, 用 "DWORD PTR QVARI+4” 指向高32位,
3. 增量指令INC
增量指令INC (Increment) 只有一个操作数, 对操作数加1(增量) 再将结果返回原处。
INC reg/mem;加:reg/mem=reg/mem+1
设计增量指令的目的, 主要是对计数器和地址指针进行调整, 所以它不影响进位CF标志,但影响其他状态标志位。例如:
inc ecx:双字量数据加1:ECX=ECX+1
inc dword ptr[ebx] ;双字量数据加1:[EBX]=[EBX]+1