XNA Math Library 函数调用之参数传递分析

1. 分析

该库定义的一个规则为,当XMVECTOR类型作为参数传递给函数时,函数的形参列表的参数声明需要符合以下规则:前三个出现的XMVECTOR类型需要声明为FXMVECTOR,之后出现的XMVECTOR类型需要声明为CXMVECTOR

xnamath.h中的原始定义为:

// Fix-up for (1st-3rd) XMVECTOR parameters that are pass-in-register for x86 and Xbox 360, but not for other targets
#if defined(_XM_VMX128_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
typedef const XMVECTOR FXMVECTOR;
#elif defined(_XM_X86_) && !defined(_XM_NO_INTRINSICS_)
typedef const XMVECTOR FXMVECTOR;
#elif defined(__cplusplus)
typedef const XMVECTOR& FXMVECTOR;
#else
typedef const XMVECTOR FXMVECTOR;
#endif

// Fix-up for (4th+) XMVECTOR parameters to pass in-register for Xbox 360 and by reference otherwise
#if defined(_XM_VMX128_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)
typedef const XMVECTOR CXMVECTOR;
#elif defined(__cplusplus)
typedef const XMVECTOR& CXMVECTOR;
#else
typedef const XMVECTOR CXMVECTOR;
#endif


可见该库针对x86平台和XBox 360平台,以及是否使用SIMD指令集的情况,给出了XMVECTOR不同的声明。

为什么这样声明?为了在不同平台和环境下保持类型名的一致,方便编程。平台的不同是指128bit寄存器的数量不同。

从原始定义中可以看出在XBox 360平台,参数的传递都是传值,x86平台只有前三个是传值,而不使用SIMD指令集的情况,则都是传递的引用。(个人观点有待验证

2.测试

测试程序包含一个简单的函数声明:

#include <windows.h>
//#define _XM_NO_INTRINSICS_
#include <xnamath.h>
#include <iostream>
using namespace std;

void test(FXMVECTOR v1, FXMVECTOR v2, FXMVECTOR v3, CXMVECTOR v4) {
}
int main() {
	XMVECTOR v[4];
	test(v[1], v[2], v[3], v[4]);
	return 0;
}


test函数的汇编代码:

void test(FXMVECTOR v1, FXMVECTOR v2, FXMVECTOR v3, CXMVECTOR v4) {
00EE1490  push        ebx  
00EE1491  mov         ebx,esp  
00EE1493  sub         esp,8  
00EE1496  and         esp,0FFFFFFF0h  
00EE1499  add         esp,4  
00EE149C  push        ebp  
00EE149D  mov         ebp,dword ptr [ebx+4]  
00EE14A0  mov         dword ptr [esp+4],ebp  
00EE14A4  mov         ebp,esp  
00EE14A6  sub         esp,128h  
00EE14AC  push        esi  
00EE14AD  push        edi  
00EE14AE  lea         edi,[ebp-128h]  
00EE14B4  mov         ecx,4Ah  
00EE14B9  mov         eax,0CCCCCCCCh  
00EE14BE  rep stos    dword ptr es:[edi]  
00EE14C0  movaps      xmmword ptr [ebp-60h],xmm2  
00EE14C4  movaps      xmmword ptr [ebp-40h],xmm1  
00EE14C8  movaps      xmmword ptr [ebp-20h],xmm0  
}


加上声明#define _XM_NO_INTRINSICS_ 后的test函数的汇编代码:(该声明的作用是不将参数传递给128bit寄存器)

void test(FXMVECTOR v1, FXMVECTOR v2, FXMVECTOR v3, CXMVECTOR v4) {
00B81490  push        ebp  
00B81491  mov         ebp,esp  
00B81493  sub         esp,0C0h  
00B81499  push        ebx  
00B8149A  push        esi  
00B8149B  push        edi  
00B8149C  lea         edi,[ebp-0C0h]  
00B814A2  mov         ecx,30h  
00B814A7  mov         eax,0CCCCCCCCh  
00B814AC  rep stos    dword ptr es:[edi]  
}


对比发现少了语句movaps,该语句功能是:移动对齐的压缩单精度浮点值。即将参数移动到三个xmm128bit寄存器。[参考]

如果将第四个参数声明为FXMVECTOR,将导致编译错误:具有 __declspec(align('16')) 的形参将不被对齐

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

superbin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值