0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

汇编语言:一个函数的编译器之旅

如意 来源:编程技术宇宙微信公众号 作者:轩辕之风O 2020-09-04 11:48 次阅读

我是一个函数

我是一个函数,名叫 str_upper,我可以把输入的字符串从小写变成大写。不信你看,我长这样:

char* str_upper(char* str, int len) {charupper[256];if (len 》= 256 || len 《= 0) return nullptr;for (int i = 0; i 《 len; i++) {if (str[i] 》= ‘a’ && str[i] 《= ‘z’) {upper[i] = str[i] - 32;} else {upper[i] = str[i]; } }returnupper;}

上面是我的源代码形式,听我的好朋友 str_lower 说,一会儿我们就要一起被送到一个叫编译器的地方加工处理了,我心里害怕极了。

编译器之旅

没多久,我们就来到了这里,一座很庞大到高楼,里面有好多精密的机器在不停的运转着。

一进入大厅,好多函数代码在这里排队等待。

我抬头向上望去,不知道有多少层楼,每一层都有一个指示牌,从下往上分别写着:

预处理

词法分析

语法分析

语义分析

···

再往上太远就看不太清楚了。

所有的函数代码按照文件为单位排好队,静静地等待着。

不过没有等太久,就轮到了我们这一队。

来了一个工作人员把我们带到了一个房间,让我们都好好躺着,一台机器快速的从头到尾扫描了一遍,将我们所在文件中出现的 #include 和 #define 全部给替换掉了。

接着,通过房间里的电梯,将我们送上了二楼。

接下来的一段时间,我们在好几层楼都做了“体检”,每个函数都被那些像 CT 一样的机器照了个遍。

不一会儿,来到了编译层,这一层有一个特别奇怪的机器,我看到一个个函数被送了进去,出来的时候都变了样子。不仅如此,接待处的工作人员看起来很凶,我这下更加紧张了。

函数调用约定

工作人员拿到了我的资料,瞅了几眼,问到:“请问你的调用约定是什么?”

我有些懵,不太懂他的意思,小声问到:“不好意思,你刚问什么?”

工作人员有点不耐烦了,提高了音量,“我是问你调用约定是什么?调用约定啊!”

看见我仍然一脸茫然,工作人员直接给我的资料上调用约定那一栏盖上了一个标记:cdecl。

我有点摸不着头脑,同行的小伙伴 str_lower 拽了我一下说到:“他是在问你函数的调用约定,就是约定调用函数的方式,涉及怎么传递参数,谁来恢复调用栈等”

他这一说我才反映过来,“这个调用约定都有哪些可选的呢?”

“一般有三种:”

cdcel,参数从右往左入栈,主调函数负责恢复栈平衡

stdcall,参数从右往左入栈,被调函数负责恢复栈平衡

fastcall,参数通过寄存器传递,寄存器不够再用栈传递

“他刚才看你没有显式声明,就默认给你 cdecl 的方式了”,小伙伴继续说到。

我点了点头,原来调用个函数还有这么多讲究呐!

Stack Canary

“别闲聊了,快进去吧!”,工作人员催我了。

我准备走向那台可怕的机器。

“唉,等一下”,正紧张着,工作人员又叫住了我。

我回头看去,工作人员正招手让我过去。

“你好,是我的代码有什么问题吗?”,我紧张的问到,生怕有错误被打回去,连累我们整个文件都要被遣返。

“不是,是我注意到你的函数里有一个局部数组,需要给你加一下栈溢出保护”,工作人员说到。

我看了下我的代码,确实有一个局部字符数组:

charupper[256];

“栈溢出保护是什么啊?”,我小声问到。

工作人员没有搭理我,忙着给我的资料上加东西。

旁边的小伙伴又把我拽了过去,说到:“咱们函数里面定义的局部变量、参数是存放在线程栈里面的。线程要不断游走在不同的函数中,调用函数后为了能回到原来的地方,调用之前把返回地址也放在了线程栈里。就像这样,你看会不会有什么问题:”

汇编语言:一个函数的编译器之旅

我仔细看了下,“哦,要是越界访问我的 upper 数组,那就可以修改返回地址,那可就危险了!”

“很聪明嘛!”

“那这个怎么加保护呢?”,我问到。

“你看,函数进来之前,先在局部变量和返回地址之间设置一个数值,函数返回之前再去检查一下,如果栈里的数据被破坏了,检查这个数值就能发现,提前抛出异常!”,小伙伴耐心的解释到。

“这样啊,那岂不是要把我打回去加上你说的这些设置和检查代码?”,我继续提问。

这时,工作人员听到了我们的闲聊,“不用,我们编译器自动添加好了,快去吧,已经处理好了”

我瞥了一眼,看到我的资料上增加了一个叫 Stack Canary 的标记。

我小心翼翼的走进了那架奇怪的机器,立刻就失去了知觉,等我醒来时,我的身体已经发生了变化,变成了一堆奇怪的代码,现在我长这样了:

汇编语言:一个函数的编译器之旅

链接

没过一会儿,我们这一队的所有函数代码都编译完成,大家从原来的.c文件都搬到了新家:一个 .o 文件,我也再次见到了小伙伴 str_lower。

“咱们是不是已经完成了编译,可以离开这里了吧?”

“还不行,编译虽然是完成了,还差链接这一步呢!”

又过了一小会儿,和我们一起过来的其他文件的函数代码也编译完成了,咱们一堆.o文件一起被送到了编译器大厦的顶楼:链接层。

这一层也有一个巨大的机器,机器背后连接了一个管道,不知通向了哪里。

我们这一批的所有 .o 文件挨个走进了这个巨大的机器,像是一条时空隧道一般,穿行于其间,我感觉到了巨大的压力把我们挤压在了一起,很快我们再一次失去了意识。

醒来之后,我发现所有的函数们都被合在了一个文件中,这是一个可执行文件,而我的身体也再次发生了变化,变成了一段段的二进制指令,现在我长这样了:

汇编语言:一个函数的编译器之旅

终于离开了编译器,真是一趟难忘的旅程,不过我再也不想来了·····彩蛋:命运开了个玩笑,第一次运行就出错!
责编AJX

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 汇编语言
    +关注

    关注

    14

    文章

    409

    浏览量

    35732
  • 函数
    +关注

    关注

    3

    文章

    4304

    浏览量

    62413
  • 编译器
    +关注

    关注

    1

    文章

    1618

    浏览量

    49043
收藏 人收藏

    评论

    相关推荐

    使用汇编语言的地方有哪些

    的每个区域之前,这些汇编指令如何集成到代码库中将根据所使用的开发环境而有所不同。通常有些自定义的编译器函数用于使编译器
    发表于 12-01 06:33

    汇编语言的学习资料分享

    寄存 cpu有多个寄存 就是cpu中可以存储数据的器件,cpu中有多个寄存
    发表于 12-06 07:16

    ARM汇编语言入门

    语言,只比处理的母语机器代码高出步。 用汇编语言编写整个程序,即使是相对简单的程序,也很复杂。这就是为什么大多数人使用C或C++等高级语言
    发表于 08-08 07:28

    汇编语言程序设计pdf

    汇编语言程序设计的内容:每种高级语言程序在连接为可执行程序之前,都必须被编译汇编语言程序,因此对于高级语言程序设计者来说,了解
    发表于 10-21 17:38 0次下载
    <b class='flag-5'>汇编语言</b>程序设计pdf

    汇编语言集成编译器(软件) 1.0版

    汇编语言集成编译器(软件) 1.0版
    发表于 03-25 08:57 0次下载

    MasmEdit汇编语言编译器

    MasmEdit汇编语言编译器.rar
    发表于 02-24 14:15 54次下载

    ARM汇编编译器的使用

    10.4 ARM汇编编译器的使用 armasm是ARM汇编语言的交叉编译器,本节将详细介绍它的使用方法。 armasm命令行语法格式如下。 armasm options inputfi
    发表于 10-19 10:14 5次下载

    编译器知识拾零

    机器代码(Machine code)。 现代编译器的主要工作流程如下: 源程序(source code)预处理(preprocessor)编
    发表于 11-07 15:44 0次下载

    TMS320C54x汇编语言工具C/C++编译器的功能优化详细概述

    该系列是套软件开发工具的支持,其中包括优化的C/C++编译器汇编器、链接,以及组合工具
    发表于 04-27 09:43 10次下载
    TMS320C54x<b class='flag-5'>汇编语言</b>工具C/C++<b class='flag-5'>编译器</b>的功能优化详细概述

    既然C编译器是C语言写,那么第一个C编译器是怎样来的?

    既然C编译器是C语言写的,那第一个C编译器是怎样来的?
    的头像 发表于 02-25 15:47 3119次阅读

    编译原理的角度看C语言如何转换成汇编语言的?

    编译原理的角度看C语言是如何转换成汇编语言的?
    的头像 发表于 02-25 15:52 2597次阅读
    从<b class='flag-5'>编译</b>原理的角度看C<b class='flag-5'>语言</b>如何转换成<b class='flag-5'>汇编语言</b>的?

    C语言代码中调用汇编函数需要注意什么

    起来看下混合语言工程中,就比如在汇编程序中调用C函数,或者在C语言代码中调用汇编函数需要注意什么
    的头像 发表于 11-12 11:04 2791次阅读

    单片机开发:为何要避免使用汇编语言

    的每个区域之前,这些汇编指令如何集成到代码库中将根据所使用的开发环境而有所不同。通常有些自定义的编译器函数用于使编译器
    发表于 11-22 20:36 10次下载
    单片机开发:为何要避免使用<b class='flag-5'>汇编语言</b>?

    汇编语言学习

    寄存 cpu有多个寄存 就是cpu中可以存储数据的器件,cpu中有多个寄
    发表于 11-23 18:06 14次下载
    <b class='flag-5'>汇编语言</b>学习

    汇编语言的变量与编码是什么

    汇编语言采用了助记符号编写程序,通过编译器转换成能够被计算机识别和处理的二进制代码程序。
    的头像 发表于 02-17 14:58 1636次阅读
    <b class='flag-5'>汇编语言</b>的变量与编码是什么