初级汇编与堆栈调用
C代码:
int a = 10;
汇编指令:
mov , prt[a];
mov , dword prt[a] ,0ah;
mov : 将一个源操作数赋值给目的操作数 push :压栈
add :加法 sub:减法 ret:返回值跳转 pop :出栈
lea : 将源操作数给出的有效地址传送到指定的的寄存器中.
ebp:栈底指针寄存器 esp:栈顶指针寄存器 pc:下一行指令寄存器
call :1、压入下一行指令地址入栈 2、栈调转被调用函数
eax、ebx、ecx、edx :寄存器(寄存器只能存放4个字节)
# include<stdio.h>
void Show()
{
printf("Hello world!")
}
int main()
{
Show();
return 0;
}
画出代码的堆栈调用图:
函数堆栈调用过程:
1、形参初始化、
2、压入下一行指令地址(next.adderss)
3、压入栈方的栈底指针寄存器值(old ebp)
4、移动ebp到被调用方的栈底
5、开辟局部变量活动所需的活动空间并初始化
函数的调用约定
extern int __cdecl Sum(int, int); //?Sum@@YAHHH@Z
extern int __stdcall Sum(int, int);//?Sum@@YGHHH@Z
extern int __fastcall Sum(int, int); //?Sum@@YIHHH@Z
1、 _ _cdecl C标准调用约定 参数按照从左至右的方式入栈 形参由调用方开辟、由调用方清理
2、 _ _stdcall Windows调用约定 参数按照从左至右的方式入栈 形参由调用方开辟,被调用方清理
3、 _ _fastcall 快速调用约定 参数按照从左至右的方式入栈 无形参开辟(使用两个寄存器来带入实参,被调用方清理)
4、 _ _thiscall 成员方法调用约定 参数按照从右至左的方式入栈 参数个数不确定时,调用方清理,否则调用方清理
约定内容 :
1、函数符号生成
2、实参的入栈顺序
3、约定形参开辟和清理方式
返回值返回方式:
0< ret <= 4 : 寄存器带回 eax
4< ret <= 8 : 两个寄存器带回 eax、 ebx
ret > 8 : 临时量带回 class