先来看一段代码:
int sum(int a, int b)
{
int temp = 0;
temp = a + b;
return temp;
}
int main()
{
int a = 10;
int b = 20;
int sum1 = sum(a, b);
cout << sum;
return 0;
}
有两个问题:
main函数调用sun,sum执行完之后怎么知道回到哪个函数?
sum函数执行完,回到main之后,怎么知道从哪一行指令继续运行?
我们现在从汇编角度看这段代码:
首先main还是会先开辟栈帧
mov dword ptr [ebp - 4],0Ah //int a = 10;
mov dword ptr [ebp - 8],14h //int b = 20;
mov eax,dword ptr [ebp - 8]
//esp存储main函数栈顶的地址 ebp存放main函数栈底地址
push eax
mov ecx,dword ptr [ebp - 4]
push ecx
call sum (01181082h)
//call指令有两个作用:调用函数;把下一条指令的地址压栈(即把add esp,8这条指令的地址压入栈中)
add esp,8
mov dword ptr [sum1],eax
下面就到sum函数了
push ebp
mov ebp,esp
sub esp,4Ch
//上述这三行汇编代码其实就是函数左括号({)所对应的代码,这三行代码的作用其实就是为sum函数开辟栈帧
mov dword ptr [temp],0
//int temp = 0
mov eax,dword ptr [ebp + 8]
//访问A
add eax,dword ptr [ebp + OCh]
//a+b
mov dword ptr [temp],eax
mov eax,dword ptr [temp]
//在return之后temp这个变量会被释放,所以把temp的值放在eax这个寄存器中
//**函数返回值如果小于等于四个字节,存放在EAX寄存器中,如果大于4小于8字节放在EAX和EBX,如果大于8字节,则产生一个临时量返回其地址
**
mov esp,ebp
pop ebp
ret
//ret的两种作用:结束调用;执行出栈操作,把主函数中调用指令的下一条指令的地址放入CPU的PC寄存器里面(PC寄存器存放CPU要执行吓一跳指令的地址)