【问题标题】:what register is returned when creating a procedure to add two XMM registers创建添加两个 XMM 寄存器的过程时返回什么寄存器
【发布时间】:2021-07-15 02:03:11
【问题描述】:

我在 C++ 上调用 ASM 函数,我希望能够返回 YMM2 存储的值,我知道过程上返回的寄存器是 RAX,我怎样才能返回 YMM2 值以及我可以在哪里返回将该值存储在 C++ 中。

.data
    vec1 real4 1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0
    vec2 real4 9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0
    
.code

SumProc proc
    vmovups ymm0, ymmworld ptr [vec1]
    vmovups ymm1, ymmworld ptr [vec2]
    
    vaddps ymm2, ymm0,ymm1
    ret
    

【问题讨论】:

  • 查看 C 编译器输出以查找返回 __m256 的函数。 godbolt.org/z/hTjfTo5bf。 (剧透警告:即使是糟糕的 Windows 非vectorcall 约定也会在 ymm0 中返回,这与将向量 args 传递给函数的方式不同。x86-64 System V 总是在 xmm/ymm 寄存器中传递和返回)
  • 您正在寻找的概念称为Application Binary Interface (ABI),每个架构甚至每个编译器都可能不同。例如,AMD64 ABI 在除 Windows 之外的所有地方都使用“浮点返回值类似地存储在 XMM0 和 XMM1 中。[25]:25 更宽的 YMM 和 ZMM 寄存器用于在传递和返回更宽的值时代替 XMM存在”
  • 你在为什么操作系统编程?

标签: c++ assembly x86-64 avx calling-convention


【解决方案1】:

您正在寻找的概念称为Application Binary Interface (ABI),它可能因架构甚至编译器而异。

例如,AMD64 ABI 在 Windows 状态以外的任何地方都使用

浮点返回值类似地存储在 XMM0 和 XMM1 中。较宽的 YMM 和 ZMM 寄存器用于在存在时代替 XMM 传递和返回较宽的值。

cmets中提到的__vectorcallWindows调用约定是一样的:

使用前四个 XMM/YMM 寄存器返回结果向量类型和 HVA 值

没有明确说明默认的 Windows 返回约定,因此最好在 godbolt.org 上尝试并查看。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 2017-10-29
    • 1970-01-01
    • 2020-02-14
    • 1970-01-01
    相关资源
    最近更新 更多