汇编基础教程(二)——常用汇编指令之运算指令
原文地址:http://www.tinpont.com/knowledge/assembly_instruction_operator.html
-------------------------------------------------------------------------------分割线--------------------------------------------------------------------------------
在上一篇我们学会了赋值部分的常用汇编指令,这次我们来学习一下运算指令。
运算指令包括加减乘除、位操作指令等可以进行运算的指令,下面我们来了解一下。
ADD加法指令(add)
此指令会设置相关Eflags寄存器,格式如下:
伪C代码为dst += src,dst可以是寄存器、地址,不可以是立即数;src可以是寄存器、地址和立即数,dst和src不能同时为地址。例如:
1
|
ADD
dst,src |
伪C代码为dst += src,dst可以是寄存器、地址,不可以是立即数;src可以是寄存器、地址和立即数,dst和src不能同时为地址。例如:
1
2
3
4
|
ADD
EAX,1 //
寄存器EAX的值加1 ADD
EAX,EBX //
寄存器EAX等于寄存器EAX加上寄存器EBX的值 ADD
EAX,[20401000] //
寄存器EAX等于寄存器EAX加上地址为20401000处的值 ADD
[02401000],EAX //
地址02401000处的值为其原值加上寄存器EAX的值 |
INC加一指令(increase)
此指令会设置相关Eflags寄存器,格式如下:
伪C代码为dst ++,dst可以是寄存器和地址,不可以是立即数。例如:
1
|
INC
dst |
伪C代码为dst ++,dst可以是寄存器和地址,不可以是立即数。例如:
1
2
|
INC
EAX //
寄存器EAX等于寄存器EAX加1 INC
BYTE
PTR [02401000] //
地址02401000处的值为其1byte大小的原值加1 |
SUB减法指令(subtract)
此指令会设置相关Eflags寄存器,格式如下:
此指令与ADD类似,伪C代码为dst -= src,示例如下:
1
|
SUB
dst,src |
此指令与ADD类似,伪C代码为dst -= src,示例如下:
1
2
3
4
|
SUB
EAX,1 //
寄存器EAX的值减去1 SUB
EAX,EBX //
寄存器EAX等于寄存器EAX减去寄存器EBX的值 SUB
EAX,[20401000] //
寄存器EAX等于寄存器EAX减去地址为20401000处的值 SUB
[02401000],EAX //
地址02401000处的值为其原值减去寄存器EAX的值 |
DEC减一指令(decrease)
此指令会设置相关Eflags寄存器,格式如下:
此指令与INC指令类似,伪C代码为dst --,例如:
1
|
DEC
dst |
此指令与INC指令类似,伪C代码为dst --,例如:
1
2
|
DEC
EAX //
寄存器EAX等于寄存器EAX减1 DEC
BYTE
PTR [02401000] //
地址02401000处的值为其1byte大小的原值减1 |
MUL/IMUL乘法指令(multiplie)
此指令会设置相关Eflags寄存器,MUL是无符号乘法指令,IMUL是带符号乘法指令,格式如下:
此指令有点特殊,需要区别记忆。
在32位下,规定寄存器EAX为乘数,dst为被乘数,其结果最大为64位,所以把EDX作为结果的高位,EAX作为结果的低位,即EDX:EAX。
在16位下,规定寄存器AX为乘数,dst为被乘数,其结果最大为32位,DX作为结果的高位,AX作为结果的低位,即DX:AX。
在8位下,规定寄存器AL为乘数,dst为被乘数,其结果最大为16位,存放于AX。
例如:
1
|
MUL/IMUL
dst |
此指令有点特殊,需要区别记忆。
在32位下,规定寄存器EAX为乘数,dst为被乘数,其结果最大为64位,所以把EDX作为结果的高位,EAX作为结果的低位,即EDX:EAX。
在16位下,规定寄存器AX为乘数,dst为被乘数,其结果最大为32位,DX作为结果的高位,AX作为结果的低位,即DX:AX。
在8位下,规定寄存器AL为乘数,dst为被乘数,其结果最大为16位,存放于AX。
例如:
1
2
3
4
5
6
7
8
|
MOV
EDX,6 //
寄存器EDX赋值6 MOV
EAX,2 //
寄存器EAX赋值2 MOV
EBX,3 //
寄存器EBX赋值3 MUL
EBX //
执行后,EBX * EAX = 2 * 3 = 6,寄存器EDX为0,寄存器EAX为6 MOV
EDX,6 //
寄存器EDX赋值6 MOV
EAX,2 //
寄存器EAX赋值2 MOV
EBX,3 //
寄存器EBX赋值3 MUL
BL //
执行后,BL * AL = 2 * 3 = 6,寄存器EDX不受影响,值为6,寄存器AX为6 |
DIV/IDIV除法指令(divide)
此指令会设置相关Eflags寄存器,DIV是无符号乘法指令,IDIV是带符号乘法指令,格式如下:
此指令有点特殊,需要区别记忆。
在32位下,规定EDX:EAX为被除数,dst为除数,其商放于寄存器EAX,余数放于寄存器EDX;
在16位下,规定DX:AX为被除数,dst为除数,其商放于寄存器AX,余数放于寄存器DX;
在8位下,规定AX为被除数,dst为除数,其商放于寄存器AL,余数放于寄存器AH。例如:
1
|
DIV/IDIV
dst |
此指令有点特殊,需要区别记忆。
在32位下,规定EDX:EAX为被除数,dst为除数,其商放于寄存器EAX,余数放于寄存器EDX;
在16位下,规定DX:AX为被除数,dst为除数,其商放于寄存器AX,余数放于寄存器DX;
在8位下,规定AX为被除数,dst为除数,其商放于寄存器AL,余数放于寄存器AH。例如:
1
2
3
4
5
6
7
8
|
MOV
EDX,0 //
寄存器EDX赋值0 MOV
EAX,7 //
寄存器EAX赋值7 MOV
EBX,2 //
寄存器EBX赋值2 DIV
EBX //
执行后,EDX:EAX / EBX = 7 / 2 = 3 % 1,EAX值为3,EDX值为1 MOV
EDX,6 //
寄存器EDX赋值6 MOV
EAX,7 //
寄存器EAX赋值7 MOV
EBX,2 //
寄存器EBX赋值2 DIV
BL //
执行后,AX / BL = 7 / 2 = 3 % 1,AL值为3,AH值为1,AX的值为0x103 |
AND逻辑与指令(and)
此指令会设置相关Eflags寄存器,格式如下:
把dst与src进行逻辑与操作,位同时为1则设为1,其他情况设为0,伪C代码dst &= src,例如:
1
|
AND
dst,src |
把dst与src进行逻辑与操作,位同时为1则设为1,其他情况设为0,伪C代码dst &= src,例如:
1
2
3
|
MOV
AL,30 //
寄存器AL赋值00110000(0x30) MOV
BL,25 //
寄存器BL赋值00100101(0x25) AND
AL,BL //
AL = AL & BL = 100000(0x20) |
OR逻辑或指令(or)
此指令会设置相关Eflags寄存器,格式如下:
把dst与src进行逻辑或操作,位同时为0则设为0,其他情况设为1,伪C代码dst |= src,例如:
1
|
OR
dst,src |
把dst与src进行逻辑或操作,位同时为0则设为0,其他情况设为1,伪C代码dst |= src,例如:
1
2
3
|
MOV
AL,30 //
寄存器AL赋值00110000(0x30) MOV
BL,25 //
寄存器BL赋值00100101(0x25) OR
AL,BL //
AL = AL | BL = 00110101(0x35) |
XOR逻辑异或指令(xor)
此指令会设置相关Eflags寄存器,格式如下:
把dst与src进行逻辑异或操作,位相同时设为0,相反时设为1,伪C代码dst ^= src,例如:
1
|
XOR
dst,src |
把dst与src进行逻辑异或操作,位相同时设为0,相反时设为1,伪C代码dst ^= src,例如:
1
2
3
4
5
|
MOV
AL,30 //
寄存器AL赋值00110000(0x30) MOV
BL,25 //
寄存器BL赋值00100101(0x25) XOR
AL,BL //
AL = AL ^ BL = 0010101(0x15) XOR
AL,BL //
AL = AL ^ BL = 00110000(0x30),执行两次之后会还原原值,多用于可解密加密 XOR
AL,AL //
AL = AL ^ AL = 0,多用于清0寄存器 |
NOT逻辑非指令(not)
此指令会设置相关Eflags寄存器,格式如下:
把src进行逻辑非操作,所有位设为相反,伪C代码src ~= src,例如:
1
|
NOT
src |
把src进行逻辑非操作,所有位设为相反,伪C代码src ~= src,例如:
1
2
|
MOV
AL,30 //
寄存器AL赋值00110000(0x30) NOT
AL //
AL = ~AL = 11001111(0xCF) |