gpt4 book ai didi

c - 如何用 gcc 优化 "don' t care"参数?

转载 作者:太空宇宙 更新时间:2023-11-04 02:31:27 24 4
gpt4 key购买 nike

有时函数不使用参数(可能是因为另一个“标志”参数未启用特定功能)。

但是,您必须指定一些内容,所以通常您只需输入 0。但如果你这样做,并且函数是外部的,gcc 将发出代码以“真正确保”参数设置为 0

有没有办法告诉 gcc 函数的特定参数无关紧要,它可以不理会当时恰好在参数寄存器中的任何值?

更新:有人问到 XY 问题。这个问题背后的上下文是我想在 x86_64 中实现一个可变参数函数,而不使用编译器可变参数支持。当参数在堆栈上时,这是最简单的,所以我声明我的函数首先采用 5 或 6 个虚拟参数,以便最后一个非可变参数和所有可变参数最终都在堆栈上。这工作正常,除了它显然不是最佳的 - 在查看汇编代码时很明显 gcc 正在将调用者中的所有这些参数寄存器初始化为零。

最佳答案

请不要认真对待以下答案。这个问题要求破解,所以你去吧。

GCC 将有效地将未初始化变量的值视为“不关心”,因此我们可以尝试利用它:

int foo(int x, int y);

int bar_1(int y) {
int tmp = tmp; // Suppress uninitialized warnings
return foo(tmp, y);
}

不幸的是,我的 GCC 版本仍然懦弱地将 tmp 初始化为零,但你的版本可能更激进:

bar_1:
.LFB0:
.cfi_startproc
movl %edi, %esi
xorl %edi, %edi
jmp foo
.cfi_endproc

另一种选择是(ab)使用内联汇编来伪造 GCC,使其认为 tmp 已定义(但实际上并未定义):

int bar_2(int y) {
int tmp;
asm("" : "=r"(tmp));
return foo(tmp, y);
}

有了这个 GCC 成功摆脱了参数初始化:

bar_2:
.LFB1:
.cfi_startproc
movl %edi, %esi
jmp foo
.cfi_endproc

请注意,内联汇编必须紧接在函数调用之前,否则 GCC 会认为它必须保留会损害寄存器分配的输出值。

关于c - 如何用 gcc 优化 "don' t care"参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42730115/

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