汇编/ ABI:来电者对大型返还类型的责任

时间:2015-05-13 01:10:01

标签: windows assembly 64-bit calling-convention

我的装配技能相当差,但我一直在努力更好地理解装配,以提高我对分析会话的理解以及优化编译器的工作方式。

在研究Windows的64位调用约定时,我从未停止在机器级别考虑过的事情之一就是给出类似这样的东西:

struct BigUdt
{
    double buf[16]; // exceeds 64 bits
};
struct BigUdt create_big_udt();

...如果我理解文档正确,create_big_udt通常会为struct BigUdt分配内存(我假设在堆栈上)并将地址返回到{{1}中的内存1}}。

因此,从集会的角度来看,我的问题是:在职责范围内离开调用者的地方是什么?我假设有人负责添加{{ 1}}在某些时候回到rax。对于尺寸不是64位的倍数的类型,还是sizeof(BidUdt)填充覆盖的类型,64位堆栈对齐也会成为一个问题吗?

p,我希望这是一个合理的问题。我发现调用者和被调用者之间的这些ABI契约与调用约定相当令人生畏,并且是目前学习程序集中最困难的部分之一。

1 个答案:

答案 0 :(得分:1)

documentation非常明确:

  

否则,调用者承担分配内存的责任   并将返回值的指针作为第一个参数传递。   然后,后续参数将一个参数移到右侧。该   RAX中的被调用者必须返回相同的指针。

所以基本上foo bar(...)变成了foo* bar(foo* retval, ...)。指针可以指向调用者想要结果的位置(通常它将是调用者堆栈帧中的局部变量的地址),这当然不受调用中涉及的堆栈操作的影响,并且始终是有效的内存,堆栈或除此以外。它永远不会“悬在风中”(如果我理解这个术语的话),因为那确实会成为一场灾难。