强制gcc在栈上传递参数

发布于 2024-10-10 23:59:31 字数 165 浏览 3 评论 0原文

有没有办法强制gcc在堆栈上传递函数的参数?

我不想使用寄存器来传递参数。

更新:我正在使用 CodeSourcery 中的arm-gcc

Is there a way to force gcc to pass the parameters of a function on the stack?

I don't want to use the registers for parameter passing.

Update: I'am using arm-gcc from CodeSourcery

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

无边思念无边月 2024-10-17 23:59:31

您可以尝试将参数包装在结构中;例如,如果您的函数是 int calc_my_sum(int x, int y) {return x+y;} 您可以按如下方式更改它(丑陋):

struct my_x_y {
    int x, y;
    my_x_y(): x(0), y(0) {} // a non-trivial constructor to make the type non-POD
};

int calc_my_sum(my_x_y x_and_y) {
    // passing non-POD object by value forces to use the stack
    return x_and_y.x + x_and_y.y;
}

或者,您可以只添加 4 个虚拟参数用完寄存器,所以其他参数将使用堆栈:

struct force_stack_usage {
    int dummy0, dummy1, dummy2, dummy3;
}

int calc_my_sum(force_stack_usage, int x, int y) {
    return x + y;
}

You can try wrapping the parameters in a structure; for example, if your function is int calc_my_sum(int x, int y) {return x+y;} you can change it as follows (ugly):

struct my_x_y {
    int x, y;
    my_x_y(): x(0), y(0) {} // a non-trivial constructor to make the type non-POD
};

int calc_my_sum(my_x_y x_and_y) {
    // passing non-POD object by value forces to use the stack
    return x_and_y.x + x_and_y.y;
}

Alternatively, you can just add 4 dummy parameters to use up the registers, so other parameters will use stack:

struct force_stack_usage {
    int dummy0, dummy1, dummy2, dummy3;
}

int calc_my_sum(force_stack_usage, int x, int y) {
    return x + y;
}
那小子欠揍 2024-10-17 23:59:31

根据: http://infocenter.arm.com/帮助/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf

前四个寄存器r0-r3(a1-a4)
用于将参数值传递到
子程序并返回结果
来自函数的值。他们还可能
用于保存中间值
在例行公事中(但是,一般来说,
仅在子例程调用之间)。

据我所知,在 ARM 上除了默认调用约定之外没有其他调用约定。原因如下:

  1. 你为什么想要这样做?您的函数无法以编译形式被其他函数调用,从而造成兼容性混乱。
  2. 除非编译器能够区分调用约定,否则对符合 ABI 的系统函数的调用将不起作用。现在,我知道过去 x86-32 有不同的调用约定,但请注意 x64更简单(AMD64 与 Microsoft 所做的任何事情相比)。为什么在设计 ARM 调用约定时,会允许这么多不同的调用约定?它会造成兼容性混乱。

According to: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf

The first four registers r0-r3 (a1-a4)
are used to pass argument values into
a subroutine and to return a result
value from a function. They may also
be used to hold intermediate values
within a routine (but, in general,
only between subroutine calls).

There are, on ARM, no other calling conventions but the default, that I know of. And here is why:

  1. Why would you want to? Your function would not be callable in compiled form by other functions, creating a compatibility mess.
  2. Your calls to system functions which comply with the ABI wouldn't work, unless the compiler was able to differentiate between calling conventions. Now, I know in the past there are different calling conventions for x86-32, but notice how x64 is simpler (AMD64 vs whatever Microsoft did). Why, when designing the ARM calling convention, would you allow so many different calling conventions? It creates a compatibility mess.
咿呀咿呀哟 2024-10-17 23:59:31

存储局部变量的位置取决于您将如何使用它。如果需要获取局部变量的地址,则局部变量只能存储在堆栈上。因此,当您向子例程传递指针时,该参数将通过堆栈传递。

Where to store a local variable is depend on how you will use it. If you need to get a local variable's address, the local variable can only be stored on the stack. So when you pass your subroutine a pointer, this parameter will be passed through the stack.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文