紧接着我们在接着往下看汇编代码:
ret = Add(a, b); 011B1443 8B 45 EC mov eax,dword ptr [ebp-14h] //把ebp-14h(b)的值放到eax里,esp指向栈顶; 011B1446 50 push eax //把eax压到栈顶 011B1447 8B 4D F8 mov ecx,dword ptr [ebp-8] //把ebp-8(a)的值放到eax里;esp指向栈顶; 011B144A 51 push ecx //把ecx压到栈顶; 011B144B E8 91 FC FF FF call _Add (011B10E1h) //call指令,调用函数;这个地方是最关键的地方 //在这里我们按F11进入函数会跳转到如下这样一条语句:011B10E1 E9 DA 02 00 00 jmp Add (011B13C0h); //我们还会发现内存里在2的上面又压进去一个地址,这个地址就是我们下面这一行汇编代码开头的地址(函数调用完返回值就要使用这个地址)。如下图所示。 011B1450 83 C4 08 add esp,8 //效果如图所示:
然后我们F11进入Add函数:
011B13C0 55 push ebp //这里压进去的其实是main函数的edp 011B13C1 8B EC mov ebp,esp 011B13C3 81 EC CC 00 00 00 sub esp,0CCh 011B13C9 53 push ebx 011B13CA 56 push esi 011B13CB 57 push edi 011B13CC 8D BD 34 FF FF FF lea edi,[ebp-0CCh] 011B13D2 B9 33 00 00 00 mov ecx,33h 011B13D7 B8 CC CC CC CC mov eax,0CCCCCCCCh 011B13DC F3 AB rep stos dword ptr es:[edi]
这里的汇编代码和之前的基本上道理是一致的,执行完效果图如下所示:
int sum = 0; 011B13DE C7 45 F8 00 00 00 00 mov dword ptr [sum],0 sum = x + y; 011B13E5 8B 45 08 mov eax,dword ptr [ebp+8] //ebp+8,此时ebp+8指向形参a; 011B13E8 03 45 0C add eax,dword ptr [ebp+0Ch] //ebp+0ch,指向形参b,把a+b放到eax里 011B13EB 89 45 F8 mov dword ptr [ebp-8],eax //ebp-8就是sum所在的位置,把eax(a+b)的值给sum,sum=5; return sum; 011B13EE 8B 45 F8 mov eax,dword ptr [ebp-8] //把sum的值再放到eax里,那么eax里存放的就是我们的返回值
效果图如下所示:
011B13F1 5F pop edi 011B13F2 5E pop esi 011B13F3 5B pop ebx //pop就是出栈的意思,esp此时指向ebx下面的空间,这三个地址相当于被回收了 011B13F4 8B E5 mov esp,ebp //把ebp的值给esp 011B13F6 5D pop ebp //ebp就是我们所存储的main函数的ebp,那么此时ebp指向main函数里面的ebp 011B13F7 C3 ret //ret指令要返回值,首先把栈顶call执行下一条指令的地址出栈,然后紧接着跳到下面这一行的地址, 这也是之前为什么要把这个地址保存,就起到了一个返回值的作用 //011B1450 83 C4 08 add esp,8 011B1450 83 C4 08 add esp,8 //esp+8直接把定义的形参跳过去,到这一步的时候,我们就是Add的栈桢已经!!!被销毁了!!! 011B1453 89 45 E0 mov dword ptr [ebp-20h],eax //eax里存放的是Add函数里sum的值,把eax的值给ebp-20h(ret)就把sum的值返回了
到这里,函数的调用过程以及栈桢的创建、销毁就讲述完了!!!
回答:问题出现的原因是代码中缺少了main函数。根据C++程序的规定,每个程序都必须有且仅有一个main函数作为程序入口,如果没有定义main函数则编译器会发生错误。因此需要在程序中添加main函数。
下面是一个简单的示例代码,其中定义了一个main函数:
#include <iostream>
int main() {
std::cout << "Hello world!" << std::endl;
return 0;
}
在这个代码中,main函数的作用是输出一句“Hello world!”的话,并且返回0。在程序运行时,这个函数将作为程序的入口点被调用。
如果你在编译过程中遇到了其他错误,可以参考编译器的错误提示,逐一解决问题。一般来说,编译器的错误提示比较准确,可以有效地指导你排查程序中的问题。
如果你的程序中有其他函数调用,需要注意函数的定义顺序以及函数的作用域范围。通常情况下,函数定义需要放在main函数之前,以保证函数在调用时已经被编译器解析。
最后,需要重申的是,编程是一门细致、耐心的工作,需要对每个步骤都进行精细的设计和测试。只有这样才能保证程序的质量和稳定性。
没定义主函数
没写main函数?