结构体在汇编中如何作为参数传递?
由于结构体的大小通常比较大,个别字段是否按顺序依次传递?
如果是,它们是否像普通参数一样按相反的顺序传递?
cdecl和stdcall之间是否有任何差异?
结构体在汇编中如何作为参数传递?
由于结构体的大小通常比较大,个别字段是否按顺序依次传递?
如果是,它们是否像普通参数一样按相反的顺序传递?
cdecl和stdcall之间是否有任何差异?
将参数放在堆栈上,将指向它们的指针放在堆栈上,将它们放入寄存器中,将它们存储在固定的内存位置中,都由你决定。我曾见过某些参数通过寄存器传递,而其他参数则通过堆栈或引用传递。
你如何转移控制权也由你决定。执行“call”指令或软件中断。旧的PDP-10体系结构有五种不同的调用子程序的方法,你需要知道使用哪一种。IBM-360架构也有许多方法。
(你想看疯狂的事吗?阅读著名的中断列表,其中包含了可用于286体系结构的所有已知软件中断调用的集合。你在MS-DOS下安装的几乎每个软件都会为此添加一些新的软件中断,并且它们都有自己的调用约定,其中许多发生了冲突。)
总的来说,最好的方法是找出其他程序员正在做什么,然后也这样做。或者详细记录你的函数,以便用户知道如何调用它。
现在,如果你的汇编语言将调用或被其他语言(如C、C++、Fortran等)调用,则需要研究由语言设计师制定的标准调用约定,这些约定通常也取决于架构。例如,在32位x86中的C语言要求参数通过堆栈传递,而在Sparc中,最多可以将五个参数传递到寄存器中,超过五个的参数则放在堆栈上。
至于结构体,C标准要求将其解包,并将各个元素作为单独的参数传递,由被调用者重新组装成结构体。如果结构非常大,则这可能会极其浪费空间,因此最好传递指向结构体的指针。
如果函数返回结构体,则调用者分配空间来接收它,并将指向该空间的指针作为“秘密”参数传递给函数。
数组始终作为指针传递。
对于Fortran,所有内容都是按引用传递的,这意味着值可以返回给任何参数。即使常量也会被放置在某个内存中,对它们的指针也会传递给所调用的子程序。(这样就可能意外更改常量的值。)
结构体(如数组)是通过引用传递的,因此作为参数时它们只是一个32位的参数(指向第一个结构体成员的指针),并且在使用cdecl和stdcall调用约定时,该指针会被推入堆栈。
如果你通过值传递数据结构,这意味着你必须将结构体的每个成员都推入堆栈给被调用者,这对性能有很大影响 - 尤其是对于大型结构体。
myarray dword 300 dup(?)
push offset myarray