这里写目录标题
mov 传送指令
- mov eax, ebx 把 ebx内容传送到eax中
- mov eax, 1001H ,把 1001H 写入eax中
mov ptr
- 格式:move 操作数1, 单位长度 ptr[地址值]
- 把 中括号里面计算结果的值,作为内存地址,取出里面的值,然后存入操作数1
- 例如:
mov eax , dword ptr[ebp - 1001H]
- 格式: 单位长度 ptr[地址值] ,操作数2
- 例如:
- mov dword ptr[ebp - 1001H] ,eax
- 作用: 取出 ptr 和 []中括号里面的地址对应的内存值.
- mov eax , dword ptr[ebp - 1001H] ,把 ebp - 1001H地址里的内容,取出来, dword是双字节大小,存入eax,因为 []里面计算的是地址,如果不加dword单位大小,就不知道从[]地址中取多长的数据复制给eax
lea 直接读取有效地址值
- lea eax ,[1001H]
- lea作用是把 中括号里的值存入 寄存器里,是去掉括号后赋值给左边寄存器
- 把[1001H]里面的地址赋值给eax,也就是把1001H赋值给eax,执行之后的结果,是 eax = 1001H
- 等价于 mov eax , 1001H
- 因为lea的[]中括号可以做运算,所以 lea eax, [ebp - 10h]可以先运算,再把结果赋值给eax.作用是直接运算地址,然后复制给eax.通常用作c++中指针变量赋值
- 通常做给c++指针赋值的时候使用这个指令,例如:
int a = 3; // mov dword ptr[ebp-01h] , 3
int *p = &a; // lea eax,[ebp-01h] , 先把 abp,01h的地址复制给eax,这里之所以不能使用 mov eax ,ebp-p1h ,是因为mov的操作数2不能直接做运算,不能做运算,但是[]可以做运算
//mov dword ptr[ebp - 18h],eax,再把eax赋值给指针p
call 调用子程序
例如 call 地址值 ,call语句执行以后,会先把eip(eip中存储着下一条cpu要执行执行的地址),把eip指向的地址压入栈中,因为call执行完以后eip就已经指向了call的下一句. 就是把call的下一句指令压入占中.这时候esp(栈指针) 会esp - 4,然后执行jmp跳转到 call 后面的地址.
然后程序就跳转到这个地址,执行子程序,子程序末尾会有ret 语句,是返回语句,返回以后会跳到之前call语句的下一句
例如:
006C4E01 call 0067D4E0
006C4E06 push esi
相当于 push 006C4E06
jmp 0067D4E0
call里面遇到ret
ret 函数返回
- 跟jmp指令差不多,也是跳转,区别是ret跳转到函数执行完以后的指令.在函数调用结束的时候用这条指令返回,返回到之前call指令调用函数之后的指令
- 函数返回值一般放在 eax中
add 加法
例如 add eax,10 ,相当于 eax = eax + 10.等价于 lea eax,[eax + 10] .注意不能等价于 mov eax ,eax +10 .因为 + 加法运算只能写在 [ ] 中括号里面,否则有语法错误.
sub 减法
跟add相反
sub eax,10 相当于 eax = eax - 10
mul 乘法
mul eax , ecx , 4 等于 eax = ecx * 4 .用于数组结构,每次ecx变化就走一个元素
div 除法
跟乘法相反
div eax,ecx, 4 相当于 eax = ecx / 4
inc 自增(increase)
例如inc eax ,相当于 eax++ ,等价于 lea eax , [eax + 1]
dec 自减
跟inc 相反 , dec eax 相当于eax–,等价于 lea eax , [eax - 1]
jmp
- jmp 地址
- 无条件跳转能到地址所在的机器指令
cmp
- 比较指令,比较结果以后,后面会跟着一个跳转指令 jne ,je之类的进行跳转
- cmp op1,op2,比较 op1和 op2是否相等,如果不相等 ,后面跟着的jne会跳转,不想等,就不跳转.
jne
- jump not equal比较结果不相等才跳转, 执行jne之前需要先执行 cmp比较指令,比较之后的结果 影响jne的跳转结果.
例如: - cmp eax,dword prt[ ebp - 10h] //比较 eax和 后面地址里面的值的结果
- jne 01234567 //如果上面比较结果不相等, 就跳转能到01234567的地址
je
跟上面的jne相反,cmp比较结果相等才跳转
push
入栈,把数值或者寄存器压入栈.每次push都是放入栈顶.
例如 push eax 或者push 0
pop
出栈,跟push相反,把栈顶的值赋值给寄存器.然后把栈顶的数给取出.
例如 pop eax,就是把栈顶的数赋值给eax,然后栈顶的值删掉.
栈底在高地址,栈顶是低地址,push是 esp - 4 pop 是esp + 4
pushad
一般在call调用的头部使用pushad,把寄存器按顺序压入栈,用来保存全部寄存器
popad
一般在call调用的尾部使用popad,把寄存器按顺序出栈,用来还原之前保存的全部寄存器
and 与
都为1才为1 ,例如: and eax,eax ,相当于eax = 1
or 或
有一个1就为1,全为0才为0,例如 or eax,eax 相当于 eax = 0
xor 异或
相同为0,不同为1,按位比较
- xor eax,ecx把eax和ecx按位异或赋值给eax
- 一般用于清零和加密操作,例如 xor eax,eax ,等于给eax = 0