gpt4 book ai didi

c++ - 使用结构参数从程序集调用 C++ 函数

转载 作者:太空狗 更新时间:2023-10-29 20:27:06 26 4
gpt4 key购买 nike

我遇到了一些意外行为,这可能意味着我没有完全理解编译器在做什么。考虑以下设计的程序:

#include <stdio.h>

#pragma pack(push, 1)
struct A {
unsigned short a;
unsigned short b;

explicit A() {
printf("construct\n");
}
~A() {
printf("destruct\n");
}
};
#pragma pack(pop)
static_assert(sizeof(A) == 4, "sizeof(A) != 4");

A __stdcall f(int p1, A p2, int p3, int p4) {
printf("%08X %08X %08X %08X\n", p1, p2, p3, p4);
return p2;
}

int main() {
__asm {
push 4
push 3
push 2
push 1
call f

}
return 0;
}

上面的程序会崩溃,但是如果我从 struct A 中删除 A()~A() 的定义,它就会崩溃't。这个问题与编译器认为参数在堆栈上的位置有关,在定义构造函数的情况下,它认为它们比它们所在的位置多 4 个字节。如果我删除构造函数,我得到的输出是这样的:

00000001 00000002 00000003 00000004

这是我所期望的,但是我得到了定义的构造函数

00000002 00000003 00000004 00000000

这显然不是我所期望的。运行前者时,函数返回 RETN 0x10,后者返回 RETN 0x14,因此看起来它认为应该有另一个参数(为什么?)。我注意到如果我将 f 更改为 void 函数,它会按预期工作。那么,有人可以向我解释发生了什么以及为什么吗?我关闭了所有优化。

最佳答案

在汇编级别,函数只能通过将简单值返回到寄存器中来返回简单值,因此如果需要返回更复杂的对象,编译器会将其视为传递指向返回值的指针对象:

void f(A *return_ptr,int p1,A p2,int p3,int p4);

但是可以进行某些优化。在您的示例中,您的类包含两个 16 位短裤,这两个 16 位短裤可以打包成一个 32 位整数并在寄存器中返回。但是,如果您定义自定义析构函数,则该类不再被认为足够简单,无法进行此优化。

关于c++ - 使用结构参数从程序集调用 C++ 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17251399/

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