2.SSE2命令の実装
2-2.構造体をアセンブリに渡す(64ビット版)
今回は
構造体をアセンブリコードに渡してみて、問題なく計算できるかを確認します。
ソリューションエクスプローラの
ソースファイルにある
Source.asmがアセンブラのコードです。
以下に内容を紹介します。
.code
;float funcSample(Vector* v)
funcSample proc
movss xmm0, dword ptr [rcx]
addss xmm0, dword ptr [rcx+4]
addss xmm0, dword ptr [rcx+8]
addss xmm0, dword ptr [rcx+12]
ret
funcSample endp
end
この関数は浮動小数点で形成された
構造体のポインタを受け取ってその要素をすべて加算し返す関数です。
単純な内容ですが
構造体の受け渡しのテストになります。
以下がC/C++側です。
#include <iostream>
struct Vector {
float x;
float y;
float z;
float w;
};
extern "C" float funcSample(Vector* v);
int main()
{
Vector v = { 1.5f,2.3f,3.4f,4.5f };
std::cout << funcSample(&v) << "\n";
}
リビルドして実行すると
11.7
...\ProjectMASM\Sample202\x64\Debug\SampleMASM.exe (プロセス 15952) は、コード 0 を伴って終了しました。
このウィンドウを閉じるには、任意のキーを押してください . . .
と表示されます。
コード解説
アセンブリ側ではまず
movss xmm0, dword ptr [rcx]
という記述があります。
ポインタの場合、最初の引数は
rcxレジスタに入りますので、そのポインタの指す場所の値をxmm0に代入します。
この構造体はfloat型のメンバですのでサイズは4バイトです、ですので次の要素の場所は
[rcx+4]になります。
addss xmm0, dword ptr [rcx+4]
同様、4バイト先を読んでいって、xmm0に加算します。
戻り値は浮動小数点ですので
xmm0の内容がC/C++側にもどされますので、そのままretします。
次のテーマは?
さて、1章からここまで、
C/C++とアセンブリの相互呼び出しをやってきました。
しかしテキストベースでは、なかなか効果がわかりません。ですので次章からはガラッと趣を変え
アセンブリコードをゲームに埋め込むということをやってみたいと思います。