您的示例的“问题”是结构太小(四个字节),因此它适合寄存器并且实际上并未在堆栈上传递。来自Itanium C++ ABI(大多数 GCC 实现使用):
在以下情况下,出于调用目的,类型被认为是非平凡的:
- 它有一个非平凡的复制构造函数、移动构造函数或析构函数,或者
- 它的所有复制和移动构造函数都被删除。
此定义应用于类类型,旨在作为 [class.temporary]p3 中类型定义的补充,其中在传递或返回类型时允许额外的临时类型。对于 ABI 而言微不足道的类型将根据底层 C ABI 的规则进行传递和返回,例如在 registers 中;通常这具有执行类型的简单副本的效果。
(强调我的)。
由于您的结构是微不足道的并且完全适合返回寄存器 ( eax
),因此它不会在堆栈上传递,而是直接在eax
. 所以这里不需要任何特别的东西。但是,如果你把它弄大一点,例如:
struct A {
int x;
int y;
int z;
};
然后它不再适合并且必须在堆栈上传递。如果将结构添加到本地类型并为函数 ( struct A func1(int z)
)指定 C++ 原型,则 IDA 执行类型降低并将其转换为具有显式参数位置的 C 样式原型:
struct A *__cdecl func1(struct A *__return_ptr __struct_ptr retstr, int z)
它目前似乎__return_ptr
没有被 IDA 或反编译器使用,只是给用户的一个注释,但理论上它可以用来使反编译的代码更接近原始 C++ 语法。