寄存器传递参数~
Visual C++编译器采用__fastcall编译传递参数时,最左边的两个不大于4个字节(DWORD)的参数分别放在ecx和edx寄存器.
Movsx指令:
movsx eax,cl 把cl进行符号扩展送到eax.
例子:
Mov bl,10001111b
Movsx ax,bl
Ax = 1111111110001111
类的非静态成员函数,默认调用方式是thiscall,每一个函数都隐含接受一个this参数,thiscall调用方式时参数从右到左,被调用函数清理传送参数的栈,只是另外通过ecx寄存器传送一个额外的this指针参数.
三、
课程中用到的指令:
Lea : 取有效地址
Lea eax,dword ptr[ebp+0Ch] ;表示把ebp+0ch的地址送到eax.
Xor : 按位异或指令
Cmp : 比较指令-
Cmp eax,ebx 实际就是用eax减ebx.
Jge:大于或者等于则跳转,
Cmp eax,ebx
Jge 00123456 如果eax大于或者等于ebx就跳转.
函数的返回值
1-
return方式返回.函数的返回值在eax里.如果eax放不下edx就放高位返回值.
2-
通过”引用”参数返回.
8 = 1000
7 = 0111
Xor 8,7
1 0 0 0
0 1 1 1
1 1 1 1
四、
局部变量:
局部变量是一个函数内部定义的变量,只有在函数内才能使用.
(就像一个大房子里面有很多个房间,每个房间里有电视和一个遥控器,这个遥控器就像个局部变量你只能在这个房里里操控电视,这只是个比喻,至于有些强悍的遥控器不于说明``)
句部变量有2种:一种用堆栈存放,一般就是sub esp,8这样,用ebp-xxxx来寻址,函数的参数用ebp+xxxx来寻址,当函数执行完后,用add esp,xxxx来平堆栈.一些编译器可能会用其他方式比如:用esp + -4,还有push eax这样的方式来申请局部变量.(目的是节省字节).
还有一种是通过寄存器,除了堆栈占用的2寄存器,还剩下6个通用寄存器可用.
全局变量:
全局变量可以在整个程序中使用,全局变量通常放在区块的(.data)中的一个位置,访问时一般直接用地址访问,如:mov eax, dword ptr [4084C0h].
42E058
数组:
数组是相同数据类型元素的集合,它们在内存中按照顺序连续存放在一起.汇编里访问数组一般是基址加上某变量来实现的. (mov eax, [406A4Bh + ebx]).
五、
if-then-else
一般先用cmp指令进行比较,然后视符号标志进行处理~
Cmp eax,eax
还有用test或or之类的逻辑指令来进行判断
条件跳转(Jcond)伪指令.
常用:
JE 相等
JNE 不相等
JZ 为0
JNZ 不为0
JCXZ CX=0
JECXZ ECX=0
--------------------------
JA 大于
JNBE 不小于或等于
JAE大于或者等于
JNB 不小于
JB 小于
JNAE 不大于或者等于
JBE 小于或等于
JNA 不大于 无符号数
-------------------------
JG 大于 有符号数
JNLE 不小于或等于
JGE 大于或等于
JNL 不小于
JL 小于
JNGE 不大于或等于
JLE 小于或等于
JNG 不大于
Switch-case是多个if-then的嵌套~
六、
转移机器码
//***************************************************************************//
操作码
伪码指令
跳转含义
跳转类型
跳转的条件(标志位)
0F 87 cw/cd JA rel16/32 大于 near (CF=0 and ZF=0)
0F 83 cw/cd JAE rel16/32 大于等于 near (CF=0)
0F 82 cw/cd JB rel16/32 小于 near (CF=1)
0F 86 cw/cd JBE rel16/32 小于等于 near (CF=1 or ZF=1)
0F 82 cw/cd JC rel16/32 进位 near (CF=1)
0F 84 cw/cd JE rel16/32 等于 near (ZF=1)
0F 84 cw/cd JZ rel16/32 为0 near (ZF=1)
0F 8F cw/cd JG rel16/32 大于 near (ZF=0 and SF=OF)
0F 8D cw/cd JGE rel16/32 大于等于 near (SF=OF)
0F 8C cw/cd JL rel16/32 小于 near (SF<>OF)
0F 8E cw/cd JLE rel16/32 小于等于 near (ZF=1 or SF<>OF)
0F 86 cw/cd JNA rel16/32 不大于 near (CF=1 or ZF=1)
0F 82 cw/cd JNAE rel16/32 不大于等于 near (CF=1)
0F 83 cw/cd JNB rel16/32 不小于 near (CF=0)
0F 87 cw/cd JNBE rel16/32 不小于等于 near (CF=0 and ZF=0)
0F 83 cw/cd JNC rel16/32 不进位 near (CF=0)
0F 85 cw/cd JNE rel16/32 不等于 near (ZF=0)
0F 8E cw/cd JNG rel16/32 不大于 near (ZF=1 or SF<>OF)
0F 8C cw/cd JNGE rel16/32 不大于等于 near (SF<>OF)
0F 8D cw/cd JNL rel16/32 不小于 near (SF=OF)
0F 8F cw/cd JNLE rel16/32 不小于等于 near (ZF=0 and SF=OF)
0F 81 cw/cd JNO rel16/32 未溢出 near (OF=0)
0F 8B cw/cd JNP rel16/32 不是偶数 near (PF=0)
0F 89 cw/cd JNS rel16/32 非负数 near (SF=0)
0F 85 cw/cd JNZ rel16/32 非零(不等于) near (ZF=0)
0F 80 cw/cd JO rel16/32 溢出 near (OF=1)
0F 8A cw/cd JP rel16/32 偶数 near (PF=1)
0F 8A cw/cd JPE rel16/32 偶数 near (PF=1)
0F 8B cw/cd JPO rel16/32 奇数 near (PF=0)
0F 88 cw/cd JS rel16/32 负数 near (SF=1)
0F 84 cw/cd JZ rel16/32 为零(等于) near (ZF=1)
注:一些指令操作数的含义说明:
rel8 表示 8 位相对地址
rel16 表示 16 位相对地址
rel16/32 表示 16或32 位相对地址
r/m16 表示16位寄存器
r/m32 表示32位寄存器
//*****************************************************************************************//
*短转移-(Short Jump):无条件转移和条件转移的机器码都是2个字节,转移范围-128~+127字节.
*长转移-(Long Jump):无条件转移的机器码是5字节,条件转移是6字节,条件转移要用2个字节表示类型(JE-JG)等```其他4个字节表示转移偏移,无条件转移用1个字节标识指令,4字节表示偏移.
EB00~EB7F向后转移,EB80~EBFF是向前转移.
位移量=目的地址-起始地址-跳转指令本身长度.