1. 堆栈相关指令
push:把一个32位的操作数压入堆栈中。这个操作导致esp被减去4。esp被称为栈顶,顶部是地址小的区域,那么压入堆栈的数据越多,esp就越来越小。在32位平台上,esp每次减少4个字节。
pop:与pop相反,esp被加4,一个数据出栈。pop的参数一般是寄存器,栈顶的数据被弹出到这个寄存器中。
虽然一般不把sub、add这些算术指令和call、ret这样的跳转指令归入堆栈相关指令中,但是实际上在函数参数传递过程中,sub和add最长用来操作堆栈;call和ret对堆栈也有影响。
sub:减法。第一个参数是被减数所在的寄存器;第二个参数是减数。
add:加法。(与sub类似)
ret:返回。相当于跳转回调用函数的地方。(对应的call指令来调用函数,返回到call之后的下一条指令)
call:调用函数。
指令对堆栈的影响:有的指令会自动的操作堆栈,这也正是call与jmp的不同之处。call会把它的下一条指令的地址压入堆栈中,然后跳转到它调用的函数的开头处;而单纯的jmp是不会这样做的。同样,ret指令也会自动地弹出返回地址。
call的本质相当于push+jmp;ret的本质相当于pop+jmp。
2. 数据传送指令
mov:数据移动。第一个参数是目的,第二个参数是来源。
xor:异或。虽然是逻辑运算指令,但是xor eax, eax这样的操作常用来代替mov eax, 0。好处是速度更快,占用字节数更少。
lea:取得第二个参数的地址后放入到前面的寄存器(第一个参数)中。注意:常用lea来做何mov同样的事情,比如赋值。
lea edi, [ebp-0cch] 等同于 mov edi, ebp-0cch 但是这样的mov指令是错误的,因为mov不支持后一个操作数写成寄存器减去数字。
stos:串存储指令。
3. 跳转与比较指令
jmp:无条件跳转。
jg:大于的时候跳转。通常前面有一条比较指令。
jl:小于的时候跳转。通常前面有一条比较指令。
jge:大于的时候跳转。通常前面有一条比较指令。
cmp:比较。往往是jg、jl、jge之类的条件跳转指令的执行条件。