1. PUSH
本质:
sub esp,4
mov dword ptr ds[ESP],数据---------把数据存储到ESP所指向的地址,也就是栈顶
2. POP
本质:
mov eax,esp地址指向的值,也就是栈顶存的值
add esp,4
3.RET
本质:
POP EIP
把栈顶的值赋给EIP,然后栈顶(ESP)地址+4
4. JMP指令:唯一作用是无条件修改EIP的值,没有对栈和寄存器产生影响。
JMP 寄存器/立即数
本质是MOV EIP,寄存器/立即数,EIP只能由JMP指令修改
5. CALL指令:
第一个作用和JMP一样,MOV EIP,寄存器/立即数。
第二个作用,把CALL指令的写一个指令地址push到栈顶(修改ESP)
CALL指令还没执行,怎么知道下一行指令的地址?
根据CALL指令占用的数据宽度,加偏移量去算,比如CALL这条指令,地址0X004183D7中数据为E8 21 00 00 00,有5个字节,下一行指令的地址就是地址偏移5
6. RET
本质是POP EIP
RET指令通常和CALL成对出现,把CALL压栈的地址POP EIP,让程序回归原来的流程
7. CMP指令:该指令是比较两个操作数是否相同
指令格式:CMP R/M,R/M/IMM
相当于SUB指令,但是只会用两个数相减来比较是否相同,相减的结果并不保存在第一个操作数中。
只会根据相减的结果来改变标志位的,当两个操作数相等的时候,零标志位置为1.
MOV EAX,100
MOV ECX,100
CMP EAX,ECX //只相减比较,判断并修改零标志寄存器,不会把EAX修改为相减结果。
CMP AX,WORD PTR DS:[405000]
CMP AL,BYTE PTR DS:[405000]
CMP EAX,DWORD PTR DS:[405000]
8. TEST指令:
指令格式:TEST R/M,R/M/IMM
该指令和CMP有一定的相似性,两个数值进行与操作,结果也不保存,但是会改变相应标志位。
与操作:1 and 1 =1;1 and 0 = 0; 0 and 1 = 0; 0 and 0 = 0
常见用法:用这个指令,可以确定某寄存器是否等于0,如果EAX的二进制某些位为 1 的话,那么运算的结果就不为零。
TEST EAX,EAX
9. MOVS //移动数据 内存-内存
MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI] //简写MOVSB 、MOVSW、MOVSD
10.STOS指令:将AL/AX/EAX的值存储到[EDI]记录的内存单元 //移动AL还是AX还是EAX由数据宽度BYTE/WORD/DWORD中选择哪个而决定的
STOS DOWRD PTR ES:[EDI] //简写STOSB、STOSW、STOSD
STOS指令将EAX的数据12345678,存储到EDI所存储的地,12FF44,并且EDI所存储的地址,会自动+4,这是STOS指令带来的特性,方向由D标志寄存器决定(STOS只认EAX,这是死知识)
REP:REP STOS这行带代码,REP指令会根据ECX存储的数值,来重复执行STOS指令,每重复一次,ECX自动-1.(REP指令只认ECX,死知识)
11. REP指令:按计数寄存器(ECX)中指定过的次数重复执行字符串指令
MOV ECX,10
REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
12. RET 8:等价于ret和esp+8两条指令,用在被调用的子函数内,用来平衡堆栈,叫做内平栈。