gpt4 book ai didi

c++ - avr-gcc:(看似)简单功能中不需要的序言/结尾

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:12:26 25 4
gpt4 key购买 nike

当尝试处理 uint64 中的单个字节时,AVR gcc⁽¹⁾ 给我一个奇怪的序言/结尾,而使用 uint32_t 编写的相同函数给了我一个单个 ret(示例函数是 NOP)。

为什么 gcc 这样做?我该如何删除它?

You can see the code here, in Compiler Explorer .

⁽¹⁾ 来自 Arduino 1.8.9 发行版的 gcc 5.4.0,参数 =-O3 -std=c++11

源代码:

#include <stdint.h>

uint32_t f_u32(uint32_t x) {
union y {
uint8_t p[4];
uint32_t w;
};
return y{ .p = {
y{ .w = x }.p[0],
y{ .w = x }.p[1],
y{ .w = x }.p[2],
y{ .w = x }.p[3]
} }.w;
}

uint64_t f_u64(uint64_t x) {
union y {
uint8_t p[8];
uint64_t w;
};
return y{ .p = {
y{ .w = x }.p[0],
y{ .w = x }.p[1],
y{ .w = x }.p[2],
y{ .w = x }.p[3],
y{ .w = x }.p[4],
y{ .w = x }.p[5],
y{ .w = x }.p[6],
y{ .w = x }.p[7]
} }.w;
}

uint32_t 版本生成的程序集:

f_u32(unsigned long):
ret

uint64_t 版本生成的程序集:

f_u64(unsigned long long):
push r28
push r29
in r28,__SP_L__
in r29,__SP_H__
subi r28,72
sbc r29,__zero_reg__
in __tmp_reg__,__SREG__
cli
out __SP_H__,r29
out __SREG__,__tmp_reg__
out __SP_L__,r28
subi r28,-72
sbci r29,-1
in __tmp_reg__,__SREG__
cli
out __SP_H__,r29
out __SREG__,__tmp_reg__
out __SP_L__,r28
pop r29
pop r28
ret

最佳答案

我不确定这是否是一个好的答案,但这是我能给出的最好答案。 f_u64() 函数的程序集在堆栈上分配 72 个字节,然后再次释放它们(因为这涉及寄存器 r28r29,它们开始保存,最后恢复)。

如果您尝试在没有优化的情况下进行编译(我也跳过了 c++11 标志,我认为这没有任何区别),那么您将看到 f_u64() 函数首先在堆栈上分配 80 个字节(类似于您在优化代码中看到的开头语句,只是使用 80 个字节而不是 72 个字节):

    in r28,__SP_L__
in r29,__SP_H__
subi r28,80
sbc r29,__zero_reg__
in __tmp_reg__,__SREG__
cli
out __SP_H__,r29
out __SREG__,__tmp_reg__
out __SP_L__,r28

这80个字节其实都用上了。首先存储参数 x 的值(8 个字节),然后进行涉及剩余 72 个字节的大量移动数据。

之后这 80 个字节被释放到堆栈上,类似于优化代码中的关闭语句:

    subi r28,-80
sbci r29,-1
in __tmp_reg__,__SREG__
cli
out __SP_H__,r29
out __SREG__,__tmp_reg__
out __SP_L__,r28

我的猜测是优化器认为可以节省用于存储参数的 8 个字节。因此它只需要 72 个字节。然后它得出结论,所有数据的移动都可以幸免。然而,它没有弄清楚这意味着堆栈上的72字节可以被节省下来。

因此,我最好的选择是这是优化器中的限制或错误(无论您喜欢如何调用它)。在这种情况下,唯一的“解决方案”是尝试打乱真正的代码以找到解决方法或将其作为编译器错误引发。

关于c++ - avr-gcc:(看似)简单功能中不需要的序言/结尾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57780290/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com