关于不同处理器的函数调用规则

关于不同处理器的函数调用规则


接前面一篇变长参数调用的记录,这次从原理上进行了进一步研究。

不同调用规则对对于编译出来的汇编影响很大的,这里之前的理解比较粗浅,尤其是一般教科书或者网上能看到的内容都比较老,这里记录一下。

这里要重点提醒一下,之前一直以为函数调用是编译器制定的规则,不同编译器的实现不同,但是现在发现这个理解是错的,其实是处理器架构规定的,所以这里和编译器有关系但是不大,编译器也是为了符合处理器规定来做的,只不过编译器有一定的自由度,但自由度不大。

首先是这个网站,里面有具体的说明。
image_1h0ho3elh19m11g0q6rqnq66t39.png-119.3kB
image_1h0ho4bev15pp1lob1m61qk4nm7m.png-126.7kB
image_1h0ho50us47c1r7tjebc3d1cht13.png-147.8kB

还有很多,这里只是简单的贴两张图以防网站丢失。

然后是这篇文章,里面说明了asmlinkage宏的定义,其实这个宏在x86平台上才有效,arm平台上没有意义。
image_1h0hob9s51n1314b8rdd1n641m6h1g.png-37.4kB

这也和我这两天的实验结果相符,我尝试给函数增加cdecl或者fastcall之类的属性,但是编译器一直会报warning。

warning: ‘cdecl’ attribute directive ignored [-Wattributes]

开始还不理解,现在看来其实是因为编译器选项是arm64,里面没有cdecl这个属性,所以才会报这个warning。

另外关于上面提到的ATPCS规则,这个网页简单的记录了一下,可以作为扫盲。

那么在这个情况下,对可变参数的获取要借助编译器自带的一些内联函数,比如:

__builtin_va_list
__builtin_va_start
__builtin_va_end
__builtin_va_copy
__builtin_next_arg
__builtin_saveregs

这里再贴一个别人实验的图,和我这边自己观察到的现象也完全一样,再aarch64中有名参数和匿名参数在栈中的位置并不是连续的,这一点要格外注意,这次的错误就是由于这里导致的。
这是别人的:
image_1h0hs1ua3sjf1qkd1f3v1u8o4kp9.png-54kB

这是我的
image_1h0hs3p9mju8d0411ta6u92thm.png-134.2kB

所以其实栈空间的分布就是这样的:
image_1h0hs4v2j8931sbd1mj017go6i13.png-82.2kB

好了,这个问题到这里基本上就结了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值