结构如何在程序集中作为参数传递

how are structs passed as parameters in assembly

如何在程序集中将结构作为参数传递?

由于结构的大小大于正常大小,因此各个字段是否按顺序传递?

如果是,它们的顺序是否与正常参数相反?

cdecl 和 stdcall 有什么区别吗?

在大多数情况下,结构作为指向结构开头的指针传递。

该函数然后将此指针加载到某个寄存器中,并通过偏移量寻址结构的字段。

结构和数组一样,通过引用传递,因此作为参数:它们只是一个 32 位参数(指向第一个结构成员的指针), 在 cdeclstdcall.

的情况下,该指针被压入堆栈

如果您通过 value 传递数据结构,这意味着您必须将堆栈上的每个结构成员推送给被调用者,这对性能有巨大影响 –特别是大型结构。

myarray dword 300 dup(?)
push offset myarray

现在这个数组已经被引用压入(第一个成员的指针)。

在汇编中,一切皆有可能,您可以按照自己喜欢的方式传递参数,前提是调用者和被调用者就其完成方式达成一致。

将参数放入栈中,将指向参数的指针放入栈中,将它们放入寄存器中,将它们存储在固定的内存位置,这一切都由你决定。我见过一些参数在寄存器中传递,而另一些参数在堆栈中传递或通过引用传递的情况。

如何转移控制权也取决于您。执行 "call" 指令,或软件中断。旧的 PDP-10 架构有五种不同的子程序调用方式,您必须知道使用哪一种。 IBM-360架构也有很多方式。

(你想看疯了吗?阅读著名的Interrupt List,它是所有已知的可用于 286 体系结构的软件中断调用的集合。实际上你在 MS-DOS 下安装的每个软件都添加了一些新的软件中断了锅,它们各自有自己的调用约定,其中许多相互冲突。)

一般来说,最好的方法是找出其他程序员在做什么,然后做同样的事情。要么,要么很好地记录您的函数,以便用户知道如何调用它。


现在,如果你的程序集要调用或被其他语言调用,如C、C++、Fortran等,那么你需要研究语言设计者制定的标准调用约定,以及哪些通常也取决于体系结构。例如,对于 32 位 x86 上的 C,参数将在堆栈上传递,而对于 Sparc,最多五个参数将在寄存器中传递,超出的任何参数都会进入堆栈。

至于结构,C 标准要求将它们解包,并将各个元素作为单独的参数传递,由被调用者重新组装成一个结构。如果结构非常大,这可能会非常浪费,因此最好传递一个指向结构的指针。

如果函数 returns 是一个结构,调用者分配 space 来接收它,并将指向该 space 的指针作为 "secret" 参数传递给函数.

数组总是作为指针传递。

对于 Fortran,一切都通过引用传递,这意味着值可以返回给任何参数。甚至常量也存储在内存中的某个地方,指向它们的指针被传递给被调用的子程序。 (因此可能会意外更改常量的值。)