数学指令
1. INCINC只有一个操作数,它将指定的操作数内容加1,再将结果送回到该操作数。INC影响SF,ZF,AF,PF,OF标志位,但不影响CF。
INC指令中操作数的类型可以是通用寄存器或存储单元,但不能是段寄存器。字节操作或者字操作均可。对于存储单元,需要在指令中说明操作数类型(字节还是字)。例:
INC EAX ;使EAX+1
INC DWORD PTR DS:[405000] ;字操作
INC WORD PTR DS:[405000] ;字节操作
2. DEC
3. ADD
两数相加不带进位,ADD指令有两个操作数,相加后的结果存放到第一个操作数中,比如“add eax,1”等价于“inc eax”;ADD也将两个寄存器相加,比如“add eax, ebx”。此外,ADD的第一个操作数还可以是存储器操作数,但是若你对该内存单元没有写权限,则会引发异常,例如“add [405000], eax”。
4. ADC
带进位的加法,两个操作数的和加上进位标志的值,结果存放到第一个操作数中,也就是在ADD的基础上再加上进位标志CF的值,其他和ADD用法一样。
5. SUB
不带进位的减法,这个指令与ADD刚好相反——它将第一个操作数减去第二个操作数的值存放到第一个操作数中。
6. SBB
带借位减法,该指令跟ADC正好相反,它计算两个操作数的差值,并且还要减去借位标志CF的值,结果存放到第一个操作数中。
7. MUL
有两种乘法,第一个种是MUL,这种是无符号数乘法,只有一个操作数,另一个操作数是EAX,结果存放到EDX:EAX中。
例:mul ecx;也就是EDX:EAX=EAX×ECX,若eax=0xfffffff7,ecx=0x09,则执行指令mul ecx后,eax×ecx=0x8ffffffaf,所以结果为edx=0x08,eax=0xffffffaf。
8. IMUL
有符号数的乘法,如指令“imul ecx”将有符号数ECX乘以EAX,结果存放到EDX:EAX中,除此之外,IMUL还允许使用多个操作数,可以有1个、2个或3个,这是与MUL不同的地方。
尽管在默认情况下是使用EAX和EDX寄存器,但是我们还可以指定其他的数据源以及目标多达三个操作数。
两个操作数时,两者相乘,并将结果存放到第一个操作数中。例:
IMUL EDX, [EBP-18];EDX × [EBP-18] -> EDX
三个操作数时,第3操作数是乘数,第2操作数是被乘数,运算结果放入第1操作数。例:
IMUL EBP, [ESI+74], FF800002;[ESI+74] × FF800002 -> EBP
正如你所看到的,这些方法中,最好的方式就是一个操作数的方式,结果存放到EDX:EAX中,这意味着拥有两倍的大小,通过两个操作数或者三个操作数无法完成的操作可以通过一个操作数的方式来完成。
9. DIV
无符号除法,DIV只有一个操作数且为除数,该操作数必须是无符号数;另一个操作数默认是EAX且为被除数,结果存放到EDX:EAX中。在此不举例说明了,有兴趣或者用到的可以用相关软件进行测试。
10. IDIV
有符号除法,IDIV指令经常被使用。如果是一个操作数的话,那么它和DIV类似,只不过操作数是有符号的,结果依然保存在EDX:EAX中。两个操作数的情况,第一个操作数除以第二个操作数,结果存放到第一个操作数中。三个操作数的情况,第二个操作数除以第三个操作数,结果存放到第一个操作数中。
由于跟MUL和IMUL类似,这里就不提供例子了。
11. XADD
交换并相加,这个指令其实就是XCHG和ADD两个简单指令的组合,相加的结果放到第1个操作数中。例如:eax=0x09, ecx=0x01, 执行指令“xadd eax, ecx”后,eax=0x0a, ecx=0x09。
12. NEG
该指令的目的是将操作数的符号取反,即如果我们有一个32位的16进制数,用NEG操作以后,结果就会取反。例如:eax=0x32,执行完指令neg eax后,eax=0xffffffce(十进制的-50,十六进制的-32)。
无符号除法,DIV只有一个操作数且为除数,该操作数必须是无符号数;另一个操作数默认是EAX且为被除数,结果存放到EDX:EAX中。在此不举例说明了,有兴趣或者用到的可以用相关软件进行测试。
10. IDIV
有符号除法,IDIV指令经常被使用。如果是一个操作数的话,那么它和DIV类似,只不过操作数是有符号的,结果依然保存在EDX:EAX中。两个操作数的情况,第一个操作数除以第二个操作数,结果存放到第一个操作数中。三个操作数的情况,第二个操作数除以第三个操作数,结果存放到第一个操作数中。
由于跟MUL和IMUL类似,这里就不提供例子了。
11. XADD
交换并相加,这个指令其实就是XCHG和ADD两个简单指令的组合,相加的结果放到第1个操作数中。例如:eax=0x09, ecx=0x01, 执行指令“xadd eax, ecx”后,eax=0x0a, ecx=0x09。
12. NEG
该指令的目的是将操作数的符号取反,即如果我们有一个32位的16进制数,用NEG操作以后,结果就会取反。例如:eax=0x32,执行完指令neg eax后,eax=0xffffffce(十进制的-50,十六进制的-32)。