当前位置: 首页 > 科技观察

进入编译器后,一个函数会发生什么?

时间:2023-03-20 21:32:57 科技观察

我是一个函数我是一个名为str_upper的函数,我可以将输入字符串从小写更改为大写。如果你不相信我,我看起来像这样:char*str_upper(char*str,intlen){charupper[256];if(len>=256||len<=0)returnullptr;for(inti=0;i='a'&&str[i]<='z'){upper[i]=str[i]-32;}else{upper[i]=str[i];}}returnupper;}以上是我的源码形式。听好朋友str_lower说一会儿要送到一个叫编译器的地方去处理,吓坏了。编译之旅结束没多久,我们就来到了这里,一座很大很高的大楼,很多精密的机器在不停地运转。一进大厅,一大堆功能码在这里排队等候。我抬头仰望。我不知道有多少层。每层楼都有一块牌子,从下往上写着:PreprocessingLexicalAnalysisClear。所有的功能代码都以文件为单位排成一行,静静等待。不过没过多久就轮到我们组了。一个工作人员来把我们带到一个房间,让我们都躺下。一台机器从头到尾快速扫描一遍,将我们所在文件中出现的#include和#define全部替换掉??。然后,通过房间里的电梯,我们被送到了二楼。在接下来的一段时间里,我们在几个楼层进行了“体检”,每一个功能都被那些类似CT的机器拍了下来。不一会儿,就来到了编译层。这一层有一台很奇怪的机器。看到每个函数都发进来了,出来就变了。不仅如此,接待处的工作人员看起来也很咄咄逼人,这让我更加紧张。函数调用约定的工作人员拿到了我的信息,看了一眼,问道:“你的调用约定是什么?”问什么?”工作人员有些不耐烦,提高了音量,“我问你什么是通话约定?callingconvention!”工作人员见我还在发呆,直接把信息中的callingconvention那一栏给了我,盖章:cdecl。我有点懵,同事str_lower一把抓住我说:“他是在问你函数的调用约定,就是调用函数的方式,如何传递参数,谁来恢复调用栈等等。”他说完我就反应过来,“什么是这个调用约定的选项?”“一般有三种:”cdcel,参数从右到左压入栈中,调用函数负责恢复栈平衡stdcall,参数从右到左上栈,被调用的函数负责恢复栈平衡fastcall,参数通过寄存器传递,寄存器不够就传递栈,我点点头,原来要注意的地方这么多打电话给f时涂油!StackCanary“别聊了,进去吧!”,工作人员催促我。我正要走向那台可怕的机器。“喂,等一下”,我正紧张,工作人员又拦住了我。我回头一看,工作人员正在招手让我过去。“您好,请问我的代码有问题吗?”我紧张地问,生怕万一有错,被打回去,我们整个档案都被遣返了。“没有,我注意到你的函数里有一个局部数组,我需要给你加上栈溢出保护。”工作人员说。我查看了我的代码,确实有一个本地字符数组:charupper[256];“什么是堆栈溢出保护?”我小声问道。工作人员不理我,忙着在我的个人资料中添加内容。旁边的小伙伴又把我拉过来说:“我们函数中定义的局部变量和参数,都是存放在线程栈中的,线程要不停地在不同的函数中徘徊,调用完函数后,为了返回到在原来的地方,返回地址也是放在调用前的线程栈中。就这样,看看会不会出问题:“我仔细看了看,”哦,如果越界访问我的上层数组,那我修改返回地址,就危险了!“如何保护它?”,我问。”看,在函数进来之前,在局部变量和返回地址之间设置一个值,然后在函数返回之前检查一下,如果栈里面的数据坏了,通过检查这个值就可以找到,并提前抛出异常!”,小伙伴耐心的解释道。“嗯,不用给我回电话,加上你说的设置和检测码吗?”,我继续追问。这时工作人员听到了我们的聊天声,“没有,我们的编译器已经自动添加了,去吧,已经处理好了。”我瞥了一眼,在我的个人资料上看到了一个名为Stack的新应用程序。金丝雀的标志。我小心翼翼地走进那台奇怪的机器,立刻失去了知觉。当我醒来的时候,我的身体已经发生了变化,变成了一堆奇怪的代码。现在我是这个样子:Link过了一会儿,我们组的所有功能代码都编译好了,大家从原来的.c文件搬到了新家:一个.o文件,我也又遇到了我的小伙伴str_lower。“编译完成了吗,你可以离开这里了吗?”“还没有,虽然已经编译完成,但还差一步衔接!”不一会,我们自带的其他文件的功能代码也编译好了,我们一堆的.o文件被送到了编译大楼的顶层:链路层。这一层还有一台巨大的机器,机器后面连接着一根管道,通向无处。我们批次里的所有.o文件一个个一个个进入这台巨大的机器,就像一条时空隧道,穿行其中,感觉一股巨大的压力把我们挤在一起,很快我们又失去了知觉。一觉醒来,发现所有的功能都组合在一个文件里,是一个可执行文件,而我的身体又变了,变成了一段二进制指令,现在的我是这个样子:终于离开了编译器,是一个难忘的旅程,却再也不想来了……转载本文请联系编程技术宇宙公众号。